jwz - normalizing audio volume on movies [entries|archive|friends|userinfo]
jwz

  www.jwz.org
  userinfo
  archive
  rss

Links
[»| [DNA Lounge] [Blog] [iCal] ]
[»| [DNA Lounge Legal Defense Fund] ]
[»| [WebCollage] [LJ WebCollage] ]

normalizing audio volume on movies [Fri, 30-Oct-2009 12:53 PM]
Previous Entry Add to Memories Tell a Friend Next Entry
[Tags|, , , ]
[music |Cabaret Voltaire -- Big Funk]

The last time I asked this I didn't get any practical answers, but that was a year ago, so I might as well ask again:

Dear Lazyweb,

How do I normalize the audio volume of a bunch of MOV and MP4 files?

The "Sound Check" option in iTunes works passably well for MP3 files, but doesn't do anything for videos. This makes it annoying to use a playlist full of music videos as a source of ambient entertainment, since the volume fluctuates wildly.

I think that a solution involving manually pulling the audio out of the movie files, normalizing it as a WAV, and re-inserting it into the movie is probably doomed to synchronization errors. So let's not.

I have tried using the "Get Info / Options / Volume Adjustment" slider manually on a few videos, but that is far too manual and annoying to do for all of them. Perhaps an approach would be to compute the volume boost desired of each movie, then set whatever ID3 tag corresponds to that slider? Or failing that, do it with Applescript?

Update: I kinda got something working with Applescript here. It fails if any video requires a volume increase of more than 100% (~6dB), but I only have a few videos of which that is true.

linkReply

Comments:
[User Picture]From: [info]edouardp
Fri, 30-Oct-2009 9:33 PM (UTC)

(Link)

OK - so assuming there is no simply and easy solution, then I guess this is where I would start with the sticky tape solution; Applescript and shell utilities.

I'm pretty sure you can get iTunes iterate through a playlist (a smart playlist of movies?) and open each movie in Quicktime Player 7. There are bound to be some examples that are sufficiently similar at http://dougscripts.com/itunes/

Then you can extract the audio as a WAVE file from Quicktime Player 7 with

tell application "QuickTime Player 7" to export document 1 to "test.wav" as wave

Then you can invoke lame on the wav file from inside Applescript (somehow - I'm sure I've seen this done)

lame test.wav  2>&1  | grep ReplayGain

that will spit out the replaygain adjustment as "ReplayGain: +1.2dB"

Then extract the dB value and convert it to an iTunes volume adjustment setting. I think the iVolume page used to have some information about the conversion, but trial and error would also work.

Finally set the volume adjustment in iTunes for the original movie file with something like (just some random applescript from the net)

tell application "iTunes" set (volume adjustment of someTrack) to 51

A few hours work to get it all going? And then a run overnight (or several nights) to do the adjustment?
[User Picture]From: [info]edouardp
Sat, 31-Oct-2009 4:03 AM (UTC)

(Link)

Got another few minutes to play around. This kinds works for me, and writes the values back into .mov files via Quicktime Player scripting (rather than the iTunes playback volume adjustment, which of course is something completely different).

Doesn't work on .mp4 files, since Quicktime Player is only pretending to be able to read and write their metadata.

Yes, a world a suck.

do shell script "rm -f /tmp/vol.wav"
tell application "QuickTime Player 7" to export document 1 to "/tmp/vol.wav" as wave
set db_string to do shell script "lame /tmp/vol.wav 2>&1 | grep ReplayGain | cut -d ':' -f 2 | c -d '+' -f 2 | cut -d 'd' -f 1"
set db to db_string as number
set adjustment to (256 + db * 42) as integer -- This is a very bad approximation
if adjustment > 512 then
set adjustment to 512
end if
if adjustment < 0 then
set adjustment to 0
end if
tell application "QuickTime Player 7"
set thetracks to tracks of document 1
repeat with thetrack in thetracks
if the kind of thetrack is "Sound" then
set sound volume of thetrack to adjustment
end if
end repeat
save document 1
end tell
[User Picture]From: [info]lionsphil
Sat, 31-Oct-2009 11:29 AM (UTC)

(Link)

Given that you're only using LAME to calculate the ReplayGain of the input data (default, desirable here), you could probably speed that up a fair bit with -f to make the encoding quick-and-dirty.
[User Picture]From: [info]jwz
Sat, 31-Oct-2009 11:47 PM (UTC)

(Link)

Since Quicktime Player can't re-write mp4 files, it seems to me that it would be better to just set the "volume" slider in iTunes than to overwrite data in the audio track in the file itself. But that slider goes from -100% to +100%. How do I convert the ReplayGain dB float value to the -100:100 range?
[User Picture]From: [info]jwz
Sun, 1-Nov-2009 2:16 AM (UTC)

(Link)

I think maybe this is it, except for that fact that about one in every couple hundred MOVs I have are ones that ffmpeg can't extract the audio from (despite playing fine in iTunes):

to movie_volume(m)
   
    set TMPFILE to "/tmp/vol.wav"
    do shell script "rm -f " & TMPFILE
   
    -- Extract the first 2 minutes of the video to the tmp WAV file, as 8 bit mono.
    set CMD to "/opt/local/bin/ffmpeg -t 120 -vn -acodec pcm_u8 " & TMPFILE
    set CMD to CMD & " -i " & {quoted form of m} & " 2>&- <&-"
    do shell script CMD
   
    -- Find the volume adjustement for that tmp WAV file. We can't do this with a pipe instead of a tmp file because ffmpeg writes bogus WAVs to stdout.
    set CMD to "lame -f " & TMPFILE & " /dev/null 2>&1"
    set CMD to CMD & " | sed -n 's/^ReplayGain: \\+*\\(-*[0-9.]*\\)dB$/\\1/p'"
    set db to do shell script CMD
   
    do shell script "rm -f " & TMPFILE
   
    -- For relative volume x, dB value is 20*log[10](x)
    -- if y=log[b](x) then x=b^y
    -- so db=20*log[10](x)
    -- and x=10^(db/20)

    set db to db as number
    set PCT to 100 * (10 ^ (db / 20.0)) - 100
   
    return PCT
end movie_volume


tell application "iTunes"
    if selection is {} then
        display dialog "Select some videos first" buttons {"Cancel"} default button 1 with icon 2 giving up after 10
    end if
    repeat with V in selection as list
        tell V
            set F to POSIX path of {location}
            set OLD to {volume adjustment}
            tell me to set NEW to movie_volume(F)
            set {volume adjustment} to {NEW}
            log {name} & ": gain " & OLD & " => " & NEW
        end tell
       
    end repeat
end tell
[User Picture]From: [info]jwz
Sun, 1-Nov-2009 2:37 AM (UTC)

(Link)

Also, a bunch of these videos require volume increases of >200%, and iTunes caps the volume adjustment value at 100%. Sigh...
[User Picture]From: [info]edouardp
Sun, 1-Nov-2009 9:17 AM (UTC)

(Link)

You could re-adjust everything with a lower base volume to give you extra headroom.

Hmmm, thinking about that for a second, it's an excellent technical solution, and a terrible practical one.

Never mind.
[User Picture]From: [info]edouardp
Sun, 1-Nov-2009 9:14 AM (UTC)

(Link)

Looking very good - I think 99.5% of the videos being able to be adjusted should be counted as a good result!
[User Picture]From: [info]cacepi
Fri, 30-Oct-2009 9:41 PM (UTC)

mp4v2

(Link)

You could try mp4track (source code here) where you edit the volume atom for the audio track:

mp4track --track-id # --volume # $file

Although I don't know if it iTunes would normalize the audio or simply boost the volume by a percentage you set (e.g. 1.5 = 50% louder).
[User Picture]From: [info]jwz
Sat, 31-Oct-2009 2:20 AM (UTC)

Re: mp4v2

(Link)

Unfortunately, half my videos are mp4 and half are mov.

That's another awesome thing about the current state of the world: you can never find a single tool that lets you manipulate both mp4 and mov containers, and the tools all have dramatically disjoint sets of capabilities.
[User Picture]From: [info]lionsphil
Fri, 30-Oct-2009 9:58 PM (UTC)

(Link)

Maybe AACgain? It lists MP4, so and works by twiddling metadata, so might manage to tweak the audio stream without breaking the video one. (Regardless, ReplayGain seems to be a good algorithm for perceived loudness—I've used MP3Gain before now on a wide range of samples and it's done a great job.)
[User Picture]From: [info]jwz
Sat, 31-Oct-2009 2:44 AM (UTC)

aacgain

(Link)

Maybe... it appears to do something. However, it only works on mp4 files, not mov (even though that web page defines "AAC" as "mp4/m4a/Quicktime"), and it makes extensive changes throughout the file. It's not just adding some tag to the header, it's changing bits all over the place. Since I have no tools for examining the structure of these files, I can't tell what it's doing, but it's doing a lot, which means it's probably modifying every frame in the audio track.
[User Picture]From: [info]lionsphil
Sat, 31-Oct-2009 11:19 AM (UTC)

Re: aacgain

(Link)

The library it uses for metadata tweaking claims to support MOV. Or do you mean you tried it, and "supports MOV" is hilarious open-source speak for "we recognise MOV and give a nice little `unimplemented' error, send patches please"?

MP3Gain, and this it appears, work by setting the gain metadata for each frame of the stream. In MP3's case, I think this is due to a lack of an overall gain metadata field (only the ReplayGain-suggested non-standard one, which naturally plenty of players are ignorant of)—I guess this is just inertia for MP4/MOV formats. (Absolute worst case, there's source.) This approach doesn't change the sample data at all, which is why they claim it's reversible (by default it will refuse to saturate values, and saves the adjustment for undo as a metadata field), and thus shouldn't affect quality or sync.

That said, I wouldn't let it run riot with your only copy of anything.

The AppleScript solution above might be better if MP4/MOV have a global volume metadata field that players actually use.
[User Picture]From: [info]jwz
Sat, 31-Oct-2009 8:07 PM (UTC)

Re: aacgain

(Link)

% aacgain -s c tst1.mov
Error: In SVQ3 atom, extra 4 bytes at end of atom
ReadAtom: invalid atom size, extends outside parent atom - skipping to end of "meta" "" 1761967686 vs 10556144
ReadAtom: invalid atom size, extends outside parent atom - skipping to end of "©ART" "Feli" 11670320 vs 10556247
ReadAtom: invalid atom size, extends outside parent atom - skipping to end of "©gen" "New " 11080631 vs 10556355
Error opening file: tst1.mov
tst1.mov is not a valid mp4/m4a file.

So maybe that means it doesn't support .mov, or maybe that means it tries but it's just crap at it. Who can tell.

[User Picture]From: [info]toolmaker
Fri, 30-Oct-2009 9:59 PM (UTC)

(Link)

From friend:

http://www.mltframework.org/twiki/bin/view/MLT/Services

Adjust an audio stream's volume level
- based on the 'normalize' utility
[User Picture]From: [info]jwz
Sat, 31-Oct-2009 2:18 AM (UTC)

(Link)

I can barely tell what that is or whether it will do what I want. I did download it, and predictably, it doesn't compile on MacOS. So tell me why I shouldn't just ignore this?
[User Picture]From: [info]toolmaker
Sat, 31-Oct-2009 3:19 AM (UTC)

(Link)

Sorry, that was from a friend who's been fiddling with audio taken from conference videos. I don't do video/audio stuff, and didn't realize the page wasn't sensical. He doesn't use OSX either. Given all of the above, you should ignore it.
From: [info]carlfk [launchpad.net]
Sat, 31-Oct-2009 4:30 AM (UTC)

cuz there's Lovin' in it

(Link)

osx user: "I could get normalize to compile,"

http://normalize.nongnu.org/ readme "I've tried to make the code as portable as possible, so I'd appreciate hearing whether normalize works on other platforms."

I was happy with normalize, but didn't like having to demux, tweak, mux.. so then I looked to melt which does all sorts of wonderful and is being actively developed.

So if you can't find something that just works, one of these may be the next best thing.
[User Picture]From: [info]behem
Sat, 31-Oct-2009 11:28 AM (UTC)

VLC?

(Link)

Have you tried VLC? It can play both MOV and MP4 and also has a handy option for normalizing audio playback using the audio/filters/volume normalizer option.
[User Picture]From: [info]jwz
Sat, 31-Oct-2009 6:42 PM (UTC)

Re: VLC?

(Link)

I hate VLC. My music videos are in iTunes with my music, where they belong.
[User Picture]From: [info]taskboy3000
Sat, 31-Oct-2009 6:49 PM (UTC)

Re: VLC?

(Link)

I really surprised to hear that you use iTunes. This isn't an open source v. Apple thing. It's just that iTunes is so, so awful to use. I dropped it awhile ago favoring anything else in its place. Do I have iPods? Sure. Those are fine. But that horrid software dongle know as iTunes is an aborted fetus.

But, I suppose, your mileage will vary.

Also, I use VLC, but may painfully aware of its limitations.
[User Picture]From: [info]edouardp
Sun, 1-Nov-2009 9:20 AM (UTC)

Re: VLC?

(Link)

VLC used to suck (a long time ago), but my opinion is that it's now an excellent video player. But iTunes is a very good music/video/podcast organiser, which VLC isn't.

iTunes and/or Quicktime Player with Perian installed is pretty close to VLC for straight forward playback...
[User Picture]From: [info]patrock
Sat, 31-Oct-2009 7:52 PM (UTC)

(Link)

give this thing a try http://www.squared5.com/ MPEG Streamclip

I think it will do what you need it to do. I've had good luck with it
[User Picture]From: [info]jwz
Sat, 31-Oct-2009 8:03 PM (UTC)

(Link)

I've used MPEG Streamclip, and as far as I can tell, it doesn't do anything even remotely like what I need. Why do you think it does?
[User Picture]From: [info]patrock
Sat, 31-Oct-2009 8:27 PM (UTC)

(Link)

well, then i misread your request. it will strip audio and convert files.

you could just burn them all to dvd or image with Toast and use the limit/compression
[User Picture]From: [info]baconmonkey
Mon, 2-Nov-2009 4:11 AM (UTC)

(Link)