ffmpeg and grep not working to extract mean_volume value - linux

I have a list of mp3 files and i want to set all mean_volume to the same db value using a script, so I enter the command for detecting the value (https://trac.ffmpeg.org/wiki/AudioVolume) and I try to grep the value but it fails and instead prints all the output from the ffmpeg command. Any thoughts?
Also tried tr instead of grep. The command I used is:
ffmpeg -i sample.mp3 -filter:a volumedetect -f null /dev/null | grep 'mean_volume'

ffmpeg console output is stderr, so you need to redirect to stdout:
ffmpeg -i input.mp3 -filter:a volumedetect -f null - 2>&1 | grep mean_volume
or for Bash 4+:
ffmpeg -i input.mp3 -filter:a volumedetect -f null - |& grep mean_volume
Result:
[Parsed_volumedetect_0 # 0x564635d62800] mean_volume: -22.6 dB
If you just want the value use awk:
ffmpeg -i input.mp3 -filter:a volumedetect -f null - |& awk -F': ' '/mean_volume/ {print $2}'
Result:
-22.6 dB

Related

How to combine two ffmpeg bin script into one script

#!/bin/bash
cmd="ffmpeg -re -i http://10.10.10.3:9981/stream/channelnumber/9 -vcodec copy -acodec copy -f mpegts udp://224.2.2.119:2001?pkt_size=188&localaddr=192.168.2.119"
until $cmd > /dev/null 2>&1 < /dev/null; do
echo "restarting ffmpeg command..."
sleep 2
cmd="ffmpeg -re -i http://10.10.10.3:9981/stream/channelnumber/15 -vcodec copy -acodec copy -f mpegts udp://224.2.2.120:2002?pkt_size=188&localaddr=192.168.2.119"
until $cmd > /dev/null 2>&1 < /dev/null; do
echo "restarting ffmpeg command..."
sleep 2
done
Combined command:
ffmpeg -i http://10.10.10.3:9981/stream/channelnumber/9 -i http://10.10.10.3:9981/stream/channelnumber/15 -map 0 -c copy -f mpegts "udp://224.2.2.119:2001?pkt_size=188&localaddr=192.168.2.119" -map 1 -c copy -f mpegts "udp://224.2.2.120:2002?pkt_size=188&localaddr=192.168.2.119"
Do not use -re for live input streams.

ffmpeg volumedetect returns unstable result

I am using ffmpeg to calculate the volume of my audio file, but I find that ffmpeg returns different values for different containers (like mp3 v.s. ogg)
Here is an example. I am using an ogg file from Wikimedia Commons, and converting it to mp3, then analyze the volume of both files. For ogg file, I get -3.0 dB for mean volume, but for mp3 file, I get -3.4 dB. When I use other files, I also get different max volume and histogram.
[user#localhost tmp]$ wget https://upload.wikimedia.org/wikipedia/commons/b/b9/Audio_Frequency_tone%2C_Middle_C%2C_C4%2C_261.63hz.ogg -O a.ogg 2> /dev/null
[user#localhost tmp]$ ffmpeg -i a.ogg a.mp3 2> /dev/null
[user#localhost tmp]$ ffmpeg -i a.ogg -af volumedetect tmp.ogg 2>&1 | grep volumedetect
[Parsed_volumedetect_0 # 0x555f69f3f4a0] n_samples: 88768
[Parsed_volumedetect_0 # 0x555f69f3f4a0] mean_volume: -3.0 dB
[Parsed_volumedetect_0 # 0x555f69f3f4a0] max_volume: 0.0 dB
[Parsed_volumedetect_0 # 0x555f69f3f4a0] histogram_0db: 27541
[user#localhost tmp]$ ffmpeg -i a.mp3 -af volumedetect tmp.mp3 2>&1 | grep volumedetect
[Parsed_volumedetect_0 # 0x55fd62be4740] n_samples: 88768
[Parsed_volumedetect_0 # 0x55fd62be4740] mean_volume: -3.4 dB
[Parsed_volumedetect_0 # 0x55fd62be4740] max_volume: -0.0 dB
[Parsed_volumedetect_0 # 0x55fd62be4740] histogram_0db: 21340
[user#localhost tmp]$
Why is this bug happening? Which one should I believe?
You're transcoding the audio. So, the output isn't identical to the input. You should get the same result if you transcode to a lossless format like WAV or FLAC.

First character disappears when piping script with ffmpeg to bash

I often create bash scripts with bash and pipe the results to bash... When I do this:
echo -e "ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null\necho foo"|bash
I get
bash: line 2: cho: command not found
Where did the 'e' of 'echo' go? What does ffmpeg do there? Other commands work fine.
Note also:
echo -e "ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null\necho foo" > /tmp/foo.sh
bash /tmp/foo.sh #works
bash < /tmp/foo.sh #doesn't
ffmpeg also reads from standard input, which it inherits from its parent process, which is the bash process reading your command line. This means ffmpeg is reading the e from echo following the new line.
One fix is to redirection standard input for ffmpeg:
echo -e "ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null < /dev/null \necho foo"|bash
However, I can't help but point out that there isn't really any reason to run a script like this. If you want it in a separate process, start a subshell:
(
ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null
echo foo
)

Check if a video file has subtitles

Is it possible to check if a video file has a subtitle using bash and get a simple answer like "yes" or "no". I don't need to know any details about the subtitles.
Maybe using ffmpeg?
This should display a 0 if subtitles are found, and 1 if not found.
ffmpeg -i video -c copy -map 0:s:0 -frames:s 1 -f null - -v 0 -hide_banner; echo $?
Bash
ffmpeg -i $filename 2>&1 | grep "Subtitle:"
Powershell
ffmpeg -i $filename 2>&1 | select-string "Subtitle:"
Explanation:
The ffmpeg command fails if no output file is provided, but the error message contains all information about the input file. The expression 2>&1 redirects error stream to standard output so it can be piped into grep/select-string command.

How to keep stderr output and also redirect it to file

I tried
ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4 2>>log.txt 2>&1
to keep stderr output and also redirect it to file.
But it failed.
However, I can keep the stderr output by
ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4 2>log.txt
You can redirect stderr to stdout with 2>&1, and then use tee command.
cmd 2>&1 | tee -a log
try this
ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4 &> log.txt
or this
nohup ffmpeg -i rtsp://172.19.1.34/live.sdp -acodec copy -vcodec copy b.mp4
and look for nohup.out after the command returns.

Resources