[solved] ffmpeg batch renormalisation

Everything about X, Gnome, KDE, ... and everything running on it

[solved] ffmpeg batch renormalisation

Postby Soapm » 2018-11-30 03:42

Can someone point me to a good place to find ffmpeg help?

I'm trying to normalize about 2K mp3 audio files while maintaining my id3 info? Currently, I have to turn my radio volume up and down with just about each song. I am looking to normalize them so the volume in the car stays close to constant.

I found the command; https://trac.ffmpeg.org/wiki/AudioVolume

Code: Select all
ffmpeg -i test.mp3 -af "volumedetect" -vn -sn -dn -f null /dev/null


Which does a great job letting me see my current volume;

Code: Select all
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] max_volume: -5.0 dB


Then I can fix it with this command;

Code: Select all
ffmpeg -i test.mp3 -af "volume=5dB" testR.mp3


This works great and does 100% what I'm trying to do...

However, I have over 2K files so am looking to do them batch style. Everything I've found including ffmpeg-normalize seems to remove the jpg or won't normalize the max_volume to 0db (or even a consistent rms value).

I found a script that supposedly can be run as a bash script (normalize.sh) but I have no idea how to modify it to work for my purposes. Or how to put it in a bash file to execute it???

Code: Select all
# Detect the max volume from this command
ffmpeg -y -i "$1/$2" -af "volumedetect" -an -vn -y -f null /dev/null
 
# Re-encode audio with this command after setting the DB level and output file name
ffmpeg -y -i "$1/$2" -af "volume=`echo $sDBLevel`dB" -c:a libmp3lame -b:a 128k "$sOutputFileName"


What I'm trying to is take all the mp3 files in folder /Jazz &

normalize them to 0db (or even a decent RMS level) and output a mp3 file with the same name to /jazz2 maintaining all the id3 tag info. Can someone help me please? Or point me to a good place for ffmpeg help? I'm sure I'm not the first one to cross this bridge, help me please...
Last edited by Soapm on 2018-12-04 09:41, edited 2 times in total.
User avatar
Soapm
 
Posts: 541
Joined: 2012-05-22 04:23

Re: ffmpeg help

Postby Head_on_a_Stick » 2018-11-30 06:20

Soapm wrote:What I'm trying to is take all the mp3 files in folder /Jazz & normalize them to 0db (or even a decent RMS level) and output a mp3 file with the same name to /jazz2 maintaining all the id3 tag info.

Code: Select all
cd Jazz
mkdir ../jazz2
for song in *.mp3 ; do ffmpeg -i $song -af "volumedetect" -vn -sn -dn -f null /dev/null && ffmpeg -i $song -af "volume=5dB" ../jazz2/$song ; done

Untested :)
dbruce wrote:Ubuntu forums try to be like a coffee shop in Seattle. Debian forums strive for the charm and ambience of a skinhead bar in Bacau. We intend to keep it that way.
User avatar
Head_on_a_Stick
 
Posts: 8322
Joined: 2014-06-01 17:46
Location: /dev/chair

Re: ffmpeg help

Postby Soapm » 2018-11-30 07:19

Thanks, now we're cooking...

It looks like your command assumes the gain will always be 5db. It could be 5db, 10db, 7db, etc...

Code: Select all
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] max_volume: -5.0 dB


The command needs to read max volume portion of the previous output and insert the results into this portion of the second command without the minus sign.

Code: Select all
"volume=5dB"


But we are moving in the right direction if only all the files needed exactly 5db to bring the max to 0db.
User avatar
Soapm
 
Posts: 541
Joined: 2012-05-22 04:23

Re: ffmpeg help

Postby dilberts_left_nut » 2018-11-30 07:25

man cut
AdrianTM wrote:There's no hacker in my grandma...
User avatar
dilberts_left_nut
 
Posts: 4913
Joined: 2009-10-05 07:54
Location: enzed

Re: ffmpeg help

Postby Head_on_a_Stick » 2018-11-30 17:36

Soapm wrote:The command needs to read max volume portion of the previous output and insert the results into this portion of the second command without the minus sign.

Ah, I see.

How about:
Code: Select all
#!/bin/sh
mkdir ${HOME}/jazz2
cd ${HOME}/Jazz
for song in *.mp3
do volume=$(ffmpeg -i $song -af "volumedetect" -vn -sn -dn -f null /dev/null)
   ffmpeg -i $song -af "volume=${volume#*-}" ../jazz2/$song
done

^ That uses "volume=5.0 dB" (&c) as the input for the -af flag, is that acceptable?

Otherwise you will have to `cut` the number out, as d_l_n suggests.
dbruce wrote:Ubuntu forums try to be like a coffee shop in Seattle. Debian forums strive for the charm and ambience of a skinhead bar in Bacau. We intend to keep it that way.
User avatar
Head_on_a_Stick
 
Posts: 8322
Joined: 2014-06-01 17:46
Location: /dev/chair

Re: ffmpeg help

Postby tynman » 2018-11-30 19:19

The original question asks for help with normalizing playback volume using ffmpeg. But have you (OP) looked at using Replaygain? Replaygain itself is a standard, but there are many implementations for its use in Linux (and Android, Windows, i-Apple). Most music players recognize Replaygain settings. I use a package in Debian called python-rgain, which provides a pretty simple means to apply Replaygain normalization settings to a directory containing audio files.
tynman
 
Posts: 85
Joined: 2016-05-03 19:48
Location: British Columbia, Canada

Re: ffmpeg help

Postby Soapm » 2018-11-30 19:55

Head_on_a_Stick wrote:
Soapm wrote:The command needs to read max volume portion of the previous output and insert the results into this portion of the second command without the minus sign.

Ah, I see.

How about:
Code: Select all
#!/bin/sh
mkdir ${HOME}/jazz2
cd ${HOME}/Jazz
for song in *.mp3
do volume=$(ffmpeg -i $song -af "volumedetect" -vn -sn -dn -f null /dev/null)
   ffmpeg -i $song -af "volume=${volume#*-}" ../jazz2/$song
done

^ That uses "volume=5.0 dB" (&c) as the input for the -af flag, is that acceptable?

Otherwise you will have to `cut` the number out, as d_l_n suggests.


Thanks again, I don't know since I'm not sure what I'm seeing. Will the line you wrote;

Code: Select all
ffmpeg -i $song -af "volume=${volume#*-}" ../jazz2/$song


run the command;

Code: Select all
ffmpeg -i test.mp3 -af "volume=5dB" testR.mp3


Using the "max_volume:" value obtained from the first command;

Code: Select all
do volume=$(ffmpeg -i $song -af "volumedetect" -vn -sn -dn -f null /dev/null)


I don't read code but if it does what I just asked them YES, we hit pay dirt. I thought that was the bash script I posted in the first post was doing but I guess there's more than one way to skin a cat. At least that's what it was advertised to do, I just don't know how to use it or modify it for my use.

Also, can you output the files to folder /Jazz2 in the current directory. I am doing this on my headless video server so I don't really use the home directory, I keep my songs backed up on my video drive and keep the other dives with restricted access.

I read the man page for cut d_l_n posted, but I tell you, those man pages read Greek to me. I wouldn't know where to begin. I don't think they write those for laymen like me, that's for people who know something about cli and coding.

Example, the person who wrote "ffmpeg-normalize" included this line in the man page;

Code: Select all
[-d] [-v] [-n] [--version] [-nt {ebu,rms,peak}]


WTF? Are you kidding me, I'm sure that means something to somebody but I'm far from that list... ROFL... I know it's telling me how to choose between ebu, rms or peak normalization but unless they give an example of the command being used with an explanation of how they work, most of us laymen have no clue what what means...

And the sad part is, the people who do understand that line probably don't need a script someone created since they can toss together a script of their own... (just saying...) :wink:
User avatar
Soapm
 
Posts: 541
Joined: 2012-05-22 04:23

Re: ffmpeg help

Postby Soapm » 2018-11-30 19:59

tynman wrote:The original question asks for help with normalizing playback volume using ffmpeg. But have you (OP) looked at using Replaygain? Replaygain itself is a standard, but there are many implementations for its use in Linux (and Android, Windows, i-Apple). Most music players recognize Replaygain settings. I use a package in Debian called python-rgain, which provides a pretty simple means to apply Replaygain normalization settings to a directory containing audio files.


Will this normalize the songs so they play right in my car?

Sounds like it works when playing them on the computer, I'm trying to normalize the files on my USB drive I use in my car.
User avatar
Soapm
 
Posts: 541
Joined: 2012-05-22 04:23

Re: ffmpeg help

Postby Head_on_a_Stick » 2018-11-30 20:08

Soapm wrote:Will the line you wrote;

Code: Select all
ffmpeg -i $song -af "volume=${volume#*-}" ../jazz2/$song


run the command;

Code: Select all
ffmpeg -i test.mp3 -af "volume=5dB" testR.mp3


Using the "max_volume:" value obtained from the first command;

Code: Select all
do volume=$(ffmpeg -i $song -af "volumedetect" -vn -sn -dn -f null /dev/null)

Yes, that's right, the output of the first ffmpeg command is stored as a variable and the contents are stripped of everything before the minus sign then used as the input for the -af flag in the second ffmpeg command.

can you output the files to folder /Jazz2 in the current directory

Yes, just replace the end of the second ffmpeg command:
Code: Select all
../jazz2/$song

with
Code: Select all
Jazz2/$song

and change the `mkdir` command also, obviously.
dbruce wrote:Ubuntu forums try to be like a coffee shop in Seattle. Debian forums strive for the charm and ambience of a skinhead bar in Bacau. We intend to keep it that way.
User avatar
Head_on_a_Stick
 
Posts: 8322
Joined: 2014-06-01 17:46
Location: /dev/chair

Re: ffmpeg help

Postby dilberts_left_nut » 2018-11-30 20:34

Soapm wrote:WTF?
The square brackets denote optional parameters that can be used.
The curly brackets show ones to choose between.

Really, you can learn much just trying these things and see what happens.
Having a specific goal such as this is the perfect chance to learn and the knowledge gained is much more likely to "stick". Once you learn a little of what you can do, you will find a lot more opportunities to employ your new skills.

Just be careful with 'rm' and 'mv' and such, and watch where you are redirecting to with '>'.
AdrianTM wrote:There's no hacker in my grandma...
User avatar
dilberts_left_nut
 
Posts: 4913
Joined: 2009-10-05 07:54
Location: enzed

Re: ffmpeg help

Postby Head_on_a_Stick » 2018-11-30 20:35

dilberts_left_nut wrote:Having a specific goal such as this is the perfect chance to learn

+1

@OP: I am stealing your valuable opportunity here :twisted:
dbruce wrote:Ubuntu forums try to be like a coffee shop in Seattle. Debian forums strive for the charm and ambience of a skinhead bar in Bacau. We intend to keep it that way.
User avatar
Head_on_a_Stick
 
Posts: 8322
Joined: 2014-06-01 17:46
Location: /dev/chair

Re: ffmpeg help

Postby sunrat » 2018-11-30 22:08

Do you realise using ffmpeg-normalize will destroy some quality of your music? It has to decode the file first and then re-encode after normalization.
From the Github page:
Should I use this to normalize my music collection?

When you run ffmpeg-normalize and re-encode files with MP3 or AAC, you will inevitably introduce generation loss. Therefore, I do not recommend running this on your precious music collection, unless you have a backup of the originals or accept potential quality reduction. If you just want to normalize the subjective volume of the files without changing the actual content, consider using MP3Gain and aacgain.

https://en.wikipedia.org/wiki/Generation_loss

Ideally if you wish to normalize you should rip your CDs as uncompressed PCM (eg. .wav) files first, then perform the normalization and subsequently encode to a lossy format such as mp3 as you wish. Personally I prefer to keep my music as lossless FLAC but some players don't support that.
Replay Gain is a much better option but again the player must support that. It does not involve re-encoding so no quality loss. python-rgain is a useful program for that.
“ computer users can be divided into 2 categories:
Those who have lost data
...and those who have not lost data YET ”
Remember to BACKUP!
User avatar
sunrat
 
Posts: 2495
Joined: 2006-08-29 09:12
Location: Melbourne, Australia

Re: ffmpeg help

Postby Soapm » 2018-11-30 22:09

Head_on_a_Stick wrote:
dilberts_left_nut wrote:Having a specific goal such as this is the perfect chance to learn

+1

@OP: I am stealing your valuable opportunity here :twisted:


The bible says if a man steals your coat, give him your hat and gloves also so here you go... :mrgreen: :mrgreen:

Thanks a bunch for the help, I can't want to get home and try it. I've been trying for about two weeks to figure this out.

Luke 6:29 And unto him that smiteth thee on the one cheek offer also the other; and him that taketh away thy cloke forbid not to take thy coat also.
User avatar
Soapm
 
Posts: 541
Joined: 2012-05-22 04:23

Re: ffmpeg help

Postby Soapm » 2018-11-30 22:18

sunrat wrote:Do you realise using ffmpeg-normalize will destroy some quality of your music? It has to decode the file first and then re-encode after normalization.


No, which is why I come here for help. I gutted my server several years ago running a command I found on the internet to delete old kernel packages and have been gun shy every since. And I did try both Audacity and Mp3Gain but again, they remove my album art I worked so hard to code into every file. ffmpeg is the only application I've found so far that can normalize the file while maintaining the album art.

sunrat wrote:Ideally if you wish to normalize you should rip your CDs as uncompressed PCM (eg. .wav) files first, then perform the normalization and subsequently encode to a lossy format such as mp3 as you wish. Personally I prefer to keep my music as lossless FLAC but some players don't support that.
Replay Gain is a much better option but again the player must support that. It does not involve re-encoding so no quality loss. python-rgain is a useful program for that.


I didn't rip these, I "found" them already mp3. I plan to use flac when I do since my car supports that.
User avatar
Soapm
 
Posts: 541
Joined: 2012-05-22 04:23

Re: ffmpeg help

Postby Soapm » 2018-11-30 23:13

We're close and I mean man we're that close. I had to add quotes around $song variable to account for files with spaces in their names. So the script looks like this;

Code: Select all
#!/bin/sh
for song in *.mp3
do volume=$(ffmpeg -i "$song" -af "volumedetect" -vn -sn -dn -f null /dev/null)
   ffmpeg -i "$song" -af "volume=${volume#*-}" Jazz2/"$song"
   sleep 5
done


However, the files were not normalized to the correct "max_volume" value. I should have showed you the full output of the command which looks like this;

Code: Select all
chuck@lenny:/video/Music/Jazz# ffmpeg -i 20-20.mp3 -af "volumedetect" -vn -sn -dn -f null /dev/null
ffmpeg version 3.2.12-1~deb9u1 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --prefix=/usr --extra-version='1~deb9u1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libebur128 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
  libavutil      55. 34.101 / 55. 34.101
  libavcodec     57. 64.101 / 57. 64.101
  libavformat    57. 56.101 / 57. 56.101
  libavdevice    57.  1.100 / 57.  1.100
  libavfilter     6. 65.100 /  6. 65.100
  libavresample   3.  1.  0 /  3.  1.  0
  libswscale      4.  2.100 /  4.  2.100
  libswresample   2.  3.100 /  2.  3.100
  libpostproc    54.  1.100 / 54.  1.100
Input #0, mp3, from '20-20.mp3':
  Metadata:
    album           : 20/20
    artist          : George Benson
    album_artist    : George Benson
    composer        : Randy Goodrum/Steve Kipner
    genre           : Jazz
    title           : 20/20
    track           : 06
    date            : 1984
  Duration: 00:04:09.26, start: 0.025056, bitrate: 196 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 196 kb/s
    Metadata:
      encoder         : LAME3.96r
    Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 200x200 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn, 90k tbc
    Metadata:
      comment         : Other
Output #0, null, to '/dev/null':
  Metadata:
    album           : 20/20
    artist          : George Benson
    album_artist    : George Benson
    composer        : Randy Goodrum/Steve Kipner
    genre           : Jazz
    title           : 20/20
    track           : 06
    date            : 1984
    encoder         : Lavf57.56.101
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
    Metadata:
      encoder         : Lavc57.64.101 pcm_s16le
Stream mapping:
  Stream #0:0 -> #0:0 (mp3 (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
[mp3 @ 0x55f1f0d21840] Header missing speed= 441x
Error while decoding stream #0:0: Invalid data found when processing input
size=N/A time=00:04:09.19 bitrate=N/A speed= 443x
video:0kB audio:42928kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_volumedetect_0 @ 0x55f1f0d24720] n_samples: 21979102
[Parsed_volumedetect_0 @ 0x55f1f0d24720] mean_volume: -27.1 dB
[Parsed_volumedetect_0 @ 0x55f1f0d24720] max_volume: -7.8 dB
[Parsed_volumedetect_0 @ 0x55f1f0d24720] histogram_7db: 3
[Parsed_volumedetect_0 @ 0x55f1f0d24720] histogram_8db: 33
[Parsed_volumedetect_0 @ 0x55f1f0d24720] histogram_9db: 225
[Parsed_volumedetect_0 @ 0x55f1f0d24720] histogram_10db: 1038
[Parsed_volumedetect_0 @ 0x55f1f0d24720] histogram_11db: 3378
[Parsed_volumedetect_0 @ 0x55f1f0d24720] histogram_12db: 8197
[Parsed_volumedetect_0 @ 0x55f1f0d24720] histogram_13db: 16677


If you look waaaaaay down toward the end you'll see there's two "volumes" in the output. One is mean_volume and the other is max_volume. I need it to use the max_volume value and I suspect it's using the other one.

What the command is doing is upping the volume by the max_volume value which should make the new max volume 0 dB. This makes all my songs have roughly the same volume. Right now they're all over the place with the highest being about +5 but the lowest around -17 which accounts for me having to turn the volume up and down as each new song begins to play.

So either it's taking the wrong volume value or it's failing to put the dB after the value, but that usually makes the command error out when I forget the dB so I don't think it's that.

ps... Is it also possible to make it output a log file in the same directory with the songs name and the value it used to normalize? That will give me a reference to how much each song was changed. I know I'm asking a lot and am more than willing to give you my first born...
User avatar
Soapm
 
Posts: 541
Joined: 2012-05-22 04:23

Next

Return to Desktop & Multimedia

Who is online

Users browsing this forum: No registered users and 7 guests

fashionable