Losing the "Volume Shock" on iPlayer Rips

Black Hole

May contain traces of nut
Is there something I can do on an ffmpeg command line to "normalise" the volume of an mp4 file?

As a reminder of the problem, I have my HDR-FOX volume set at 18 so there is no change in volume switching between the TV internal tuner and the HDR via HDMI. If I run iPlayer (or play back an iPlayer rip), I have to reduce the HDR volume to 8 or 9 (and then put it back again afterwards). If ffmpeg can re-encode the audio stream at a reduced volume, it would avoid that problem. Could even be a new WebIF OPT+ option!

No, I am not interested in arguments about resolution and dynamic range of the source material, I just want to reduce the volume at source.
 
Partial success, I can get the Humax to reduce the volume of an mp3 but not the audio track on an mp4 video (Yet). vol 256 = same, vol 512 = +6db, vol 125 = -6db
Code:
humax# ffmpeg -i input.mp3 -vol 12 output.mp3
As -vol 128 was hardly noticable I did -vol 12 which is a lot quieter (actually 27 db quieter)
 
You can probably do this on the humax by turning experimental mode on...

Code:
humax# ffmpeg -i infile.mp4 -vol 64 -strict experimental outfile.mp4

Is it really worth doing though? I tried this on my Humax and it processed about 2 frames a second. On my i7 2600K it does 148 frames a second. It's what I'd expect from a wee MIPs processor though.
 
Yes, the experimental mode did the trick, I got 7 frames per second and it did reduced the volume as expected, however it seems to have produced a new video of much poorer quality, it also used 100% CPU time while processing the file
 
If you compare the infile and outfile files using "ffmpeg -i filename" you can see what has been changed. It's too frustrating using the Humax to do this for me so I use the Windows version on my PC (much faster processor).

It seems to reduce the video bitrate (and increase the audio bitrate!) by default:

Before:
Code:
Duration: 00:29:43.12, start: 0.000000, bitrate: 1500 kb/s
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, s16, 94 kb/s

After:
Code:
Duration: 00:29:43.15, start: 0.000000, bitrate: 889 kb/s
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, s16, 128 kb/s

So you could try forcing the video and audio bitrates of the original file, in this case it's 1500 kb/sec video, and 94k for audio...
Code:
humax# ffmpeg -i infile.mp4 -vol 64 -b:v 1500k -b:a 94k -strict experimental outfile.mp4

In my example I was using Charlie Brooker's Weekly Wipe Episode 3. It's a 30 minute video - I should use something shorter for experimentation.
 
Wow! Thanks for having a play. I expected the performance would be much better if only processing the audio track, so I guess it's not worth it for the limited benefit.
 
Actually I was just messing with ffmpeg a bit more, and it looks like you can leave the video stream alone by using "-vcodec copy":

Code:
humax# ffmpeg -i cbww1_3.mp4 -vcodec copy -vol 64 -strict experimental outfile.mp4

This allowed me to achieve 17fps during processing on the Humax (far better than 2fps when it was also processing the video stream). Now my video is 29 minutes 43 seconds and contains 44575 frames. If I process at 17fps, I can finish the video in approx 45 minutes. I'm not sure if this is acceptable but perhaps once people save off the iPlayer file, a ffmpeg job can be kicked off to reduce the volume, but it might take 50% longer than the video duration to process.

The alternative is to process it on your PC. I think Handbrake mp4 software (freeware) can modify the volume if you click on the Audio tab, then the Advanced button. You get a dB audio slider widget that lets you adjust.
 
Here's another idea if processing on the Humax is too slow.

According to the ffmpeg manual, you can detect the volume of a stream:
Code:
humax# ffmpeg -i infile.mp4 -t 5 -filter:a volumedetect -vn -f null /dev/null

The above command will read only the first 5 seconds of the stream (-t 5). We don't want to read the whole file as it takes too long.

However I can not get this to work, possibly due to this bug:

https://ffmpeg.org/trac/ffmpeg/ticket/1727

If we had a ffmpeg binary with this fix, would it be possbile to write something where it uses ffmpeg to detect the volume of the audio stream and then automatically adjust the volume of the Humax unit to compensate?

It's either that or run ffmpeg manually on a PC. FYI, on my PC it took 30 seconds processing time to lower the volume on a 30 minute video:
Code:
C:\> ffmpeg -i cbww1_3.mp4 -vcodec copy -vol 64 outfile.mp4
 
The -vcodec copy worked in retaining the video quality and increased the frame rate to 24fps

I got the volumedetect to return results when run on the Humax, but with no volume detect lines (Below), I tried this with and without the -t e.g.
ffmpeg -i 'ELEMENT SONG.mp4' -t 15 -filter:a volumedetect -vn -f null /dev/null
and
ffmpeg -i 'ELEMENT SONG.mp4' -filter:a volumedetect -vn -f null /dev/null

the example in your link is working on a *.wav file whereas the audio in my mp4 is aac e.g. I think this is why it's not working

Stream mapping:
Stream #0:0 -> #0:0 (aac -> pcm_s16le)
Press [q] to stop, [?] for help

[NOTE volume detect line missing from here]

size= 0kB time=00:01:26.47 bitrate= 0.0kbits/s
video:0kB audio:14896kB global headers:0kB muxing overhead -100.000000%

These lines are not present in my results (Taken from the example in the link above)
[Parsed_volumedetect_0 @ 0x7fb308420580] n_samples: 960800
[Parsed_volumedetect_0 @ 0x7fb308420580] mean_volume: -51.3 dB
[Parsed_volumedetect_0 @ 0x7fb308420580] max_volume: -33.9 dB
 
This is looking more like it! A longish processing time is acceptable if it can be started and left to process in its own time without disturbing normal operations - maybe by magic folder. Then there is a choice - if playback of the rip is urgent, accept it will be at high volume, or if it is less urgent (usually if pre-planned) process it and accept it will take some time.
 
I can see examples on the internet that volumedetect in video files. Perhaps we need a newer version of ffmpeg since the one in the advanced package list is nearly 1 year old:

Code:
humax# ffmpeg
ffmpeg version 0.10 Copyright (c) 2000-2012 the FFmpeg developers
  built on Feb 29 2012 10:25:07 with gcc 4.2.0 20070124 (prerelease) - BRCM 11ts-20090508
If you are happy enough with 50% extra time to process perhaps we don't need to go down the volumedetect route. But we might have more options in the future if we keep ffmpeg up-to-date.
 
The problem I see with volumedetect is the only way we have to control the Humax volume is through the ir package. If the .MP4 is batch modified to reduce the encoded volume, it will be correct any and every time it gets played. To use the volumedetect method instead of reducing the encoded volume would mean a WebIF operation to trigger the volume analysis and volume down inputs through an ir macro (hardly necessary to do the analysis - I know it needs to go down about 8 clicks, and could easily create a macro to do exactly that), and then another WebIF access to restore the volume afterwards.

I suppose it is possible to monitor disk accesses, and when read access to an mp4 file is detected reduce the volume - but that would take af123's cleverness.

Another idea: is there some kind of master output level parameter encoded in the audio stream? If there is, changing this to something lower would be a much quicker process.
 
I found a program on the internet called aacgain (based on mp3gain) which claims to normalize volume. Both are available for Linux. Unfortunately it looks like it only works on audio files and not video. So you'd have to de-mux the audio stream from the video using ffmpeg, run aacgain and then re-mux again with ffmpeg.

The whole operation might end up taking longer than using ffmpeg to change the volume on the audio stream.
 
Back
Top