[FFmpeg-devel] [PATCH] tools: add audio normalize script example.

Stefano Sabatini stefasab at gmail.com
Mon Mar 25 11:31:18 CET 2013


On date Sunday 2013-03-24 10:23:08 +0100, Clément Bœsch encoded:
> On Sun, Mar 24, 2013 at 12:40:40AM +0100, Stefano Sabatini wrote:
> [...]
> > > +ebumeta=$($analysis_cmd "amovie='$in',ebur128=metadata=1")
> > 
> > Note: this is broken in case $in contains filtergraph special chars
> > ("," or ":"), using tools/ffescape to fix it may be a possibility.
> > 
> 
> Calling tools/ffescape will cause some path problems depending on the
> setup. I'd better leave it aside for now, or escape manually in the
> script.
> 
> > > +[ $? -ne 0 ] && exit 1
> > > +for i in $(echo "$ebumeta" | xargs); do
> > > +    [ "$i" != "" ] && loudness=$i
> > > +done
> > > +adjust=$(echo "$ref-($loudness)"|bc)
> > > +if [ "$adjust" = "0" ]; then
> > > +    echo "No normalization needed for $in"
> > > +else
> > > +    echo "Adjust $in by ${adjust}dB"
> > > +    set -x
> > > +    ${FFPATH}ffmpeg -i "$in" -af volume=${adjust}dB $ffopt "$out"
> > > +fi
> > 
> > The script would be nicer if written in Perl/Python/Equivalent, but
> > don't consider this like a blocker.
> 
> Sure whatever; rewritten in Python.
> 
> -- 
> Clément B.

> From 1b55312a028a56fcabc257c9a09b1d2c045198f1 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= <ubitux at gmail.com>
> Date: Mon, 18 Mar 2013 04:02:51 +0100
> Subject: [PATCH] tools: add audio normalize script example.
> 
> ---
>  tools/normalize.py | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
>  create mode 100755 tools/normalize.py
> 
> diff --git a/tools/normalize.py b/tools/normalize.py
> new file mode 100755
> index 0000000..ef058bc
> --- /dev/null
> +++ b/tools/normalize.py
> @@ -0,0 +1,33 @@
> +#!/usr/bin/env python2
> +
> +import sys, subprocess
> +
> +if len(sys.argv) > 1:
> +    ifile  = sys.argv[1]
> +    encopt = sys.argv[2:-1]
> +    ofile  = sys.argv[-1]
> +else:
> +    print 'usage: %s <input> [encode_options] <output>' % sys.argv[0]
> +    sys.exit(1)
> +
> +analysis_cmd  = 'ffprobe -v error -of compact=p=0:nk=1 '
> +analysis_cmd += '-show_entries frame=metadata:tags=lavfi.r128.I -f lavfi '

-show_entries frame_tags=lavfi.r128.I

looks more correct.

-show_entries "frame=metadata : tags=lavfi.r128.I"

means show frame=metadata ("metadata" field in frame, which is
non-existing), and tags=lavfi.r128.I, that is all the tags matching
the key "lavfi.r128.I", while we only want to show the one in
frame_tags.

> +analysis_cmd += "amovie='%s',ebur128=metadata=1" % ifile
> +try:
> +    probe_out = subprocess.check_output(analysis_cmd, shell=True)
> +except subprocess.CalledProcessError, e:
> +    sys.exit(e.returncode)
> +loudness = ref = -23
> +for line in probe_out.splitlines():
> +    sline = line.rstrip()
> +    if sline:
> +        loudness = sline

A potentially simpler approach would consist into sending the last
value when we close the filter (such as lavfi.r128.eof.I), so we don't
have to process all the previous values just to find the last one.

> +adjust = ref - float(loudness)
> +if abs(adjust) < 0.0001:
> +    print 'No normalization needed for ' + ifile
> +else:
> +    print "Adjust %s by %.1fdB" % (ifile, adjust)
> +    norm_cmd  = ['ffmpeg', '-i', ifile, '-af', 'volume=%fdB' % adjust]
> +    norm_cmd += encopt + [ofile]
> +    print ' => %s' % ' '.join(norm_cmd)
> +    subprocess.call(norm_cmd)

Looks good oterwise.
-- 
FFmpeg = Fantastic Formidable Mean Powerful Exciting Geek


More information about the ffmpeg-devel mailing list