Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > General > Audio encoding
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 22nd December 2013, 08:44   #1  |  Link
hydra3333
Registered User
 
Join Date: Oct 2009
Location: crow-land
Posts: 540
? adjusting loudness with ffmpeg

Looking for assistance with a windows .bat script to adjust loudness and convert to .mp2, via ffmpeg.

Can someone suggestion a simpler way to do it than below ?

So...

the outputs from these look interesting:
Code:
".\ffmpeg.exe" -y -vn -nostats -threads 8 -i ".\test.mpg" -af volumedetect -f null - > vol.max.txt 2>&1
".\ffmpeg.exe" -y -vn -nostats -threads 8 -i ".\test.mpg" -filter_complex ebur128 -f null - > vol.ebur128.txt 2>&1
If I can somehow in DOS extract the value from lines in those files into variables, eg
Quote:
[Parsed_volumedetect_0 @ 049ae8a0] max_volume: -7.7 dB
in this case into VOLM=-7.7
and
Quote:
I: -25.1 LUFS
in this case into VLUFS=-25.1
and then, in DOS, calculate
Code:
adjVOLM=min(abs(VOLI),16)
adjLUFS= min(abs(max(-23-VLUFS,0)),16)
Then I can choose which to use for ffmpeg volume adjustment
eg
Code:
ffmpeg  ...volume=volume=%myvariabe%dB:precision=float  ...
I'm not really sure whether to use the LUFS number or the max loudness number from "-af volumedetect". Which is "best" pragmatically ?

Anyway, here's the brute force way - looking forward to suggestions on a simpler way to do it.

Code:
@echo off
@setlocal ENABLEDELAYEDEXPANSION

@echo on
SET volFile=.\max.vol.vol.txt
".\ffmpeg.exe" -y -vn -nostats -threads 8 -i ".\test.mpg" -af volumedetect -f null - > %volFile% 2>&1
SET vbsf_vol=".\000-f1.vol.vbs"
REM @echo off
ECHO ' read vol from ffmpeg file and return the Maximum Volume value only > %vbsf_vol%
ECHO Const ForReading = 1 >> %vbsf_vol%
ECHO Dim objStdOut, objFSO , objFile, line, e, s, v, adj, er  >> %vbsf_vol%
ECHO 'Set objStdOut = WScript.StdOut  >> %vbsf_vol%
ECHO Set objFSO = CreateObject("Scripting.FileSystemObject") >> %vbsf_vol%
ECHO Set objFile = objFSO.OpenTextFile("!volFile!", ForReading) >> %vbsf_vol%
ECHO er = 1 >> %vbsf_vol%
ECHO v = 0 >> %vbsf_vol%
ECHO adj = 0 >> %vbsf_vol%
ECHO Do Until objFile.AtEndOfStream >> %vbsf_vol%
ECHO    line = lcase(objFile.ReadLine) >> %vbsf_vol%
ECHO    if instr(line,lcase("max_volume:")) > 0 then >> %vbsf_vol%
ECHO       s = instr(line,lcase("max_volume:")) + 11 >> %vbsf_vol%
ECHO       e = instr(line,lcase("dB")) - 1 >> %vbsf_vol%
ECHO       'WScript.StdOut.WriteLine "line=" ^& line >> %vbsf_vol%
ECHO       'WScript.StdOut.WriteLine s ^& " " ^& e  >> %vbsf_vol%
ECHO       if s^<=0 or e^<=0 then  >> %vbsf_vol%
ECHO          exit do >> %vbsf_vol%
ECHO       end if >> %vbsf_vol%
ECHO       v = trim(mid(line,s,e-s+1)) >> %vbsf_vol%
ECHO       'WScript.StdOut.WriteLine "string v=" ^& v >> %vbsf_vol%
ECHO       v = cdbl(v) >> %vbsf_vol%
ECHO       'WScript.StdOut.WriteLine "cdbl v=" ^& v >> %vbsf_vol%
ECHO       adj = min(abs(v),16) >> "%vbsf_vol%"
ECHO       adj = max(adj-1,0) >> "%vbsf_vol%"
ECHO       'WScript.StdOut.WriteLine "adj=" ^& adj >> %vbsf_vol%
ECHO       er = 0 >> %vbsf_vol%
ECHO       exit do >> %vbsf_vol%
ECHO    end if >> %vbsf_vol%
ECHO Loop >> %vbsf_vol%
ECHO WScript.StdOut.WriteLine adj >> %vbsf_vol%
ECHO objFile.Close >> %vbsf_vol%
ECHO set objFile = nothing >> %vbsf_vol%
ECHO set objFSO = nothing >> %vbsf_vol%
ECHO wscript.quit(er) ' 1=error. 0=ok >> %vbsf_vol%
ECHO function Max(a,b) >> %vbsf_vol%
ECHO     Max = a >> %vbsf_vol%
ECHO     If b ^> a then Max = b >> %vbsf_vol%
ECHO end function >> %vbsf_vol%
ECHO function Min(a,b) >> %vbsf_vol%
ECHO     Min = a >> %vbsf_vol%
ECHO     If b ^< a then Min = b >> %vbsf_vol%
ECHO end function  >> %vbsf_vol%
for /f "tokens=*" %%i in ('cscript //B //NOLOGO %vbsf_vol%') do set adjVOL=%%i
ECHO The value adjVOL=!adjVOL!

pause

@echo on
set ebur128File=max.vol.ebur128.txt
".\ffmpeg.exe" -y -vn -nostats -threads 8 -i ".\test.mpg" -filter_complex ebur128 -f null - > %ebur128File% 2>&1
SET vbsf_ebur128=".\000-f1.ebur128.vbs"
@echo off
ECHO ' read ebur128 from ffmpeg file and return the Integrated Loudness I value only > %vbsf_ebur128%
ECHO Const ForReading = 1 >> %vbsf_ebur128%
ECHO Dim objStdOut, objFSO , objFile, line, e, s, v, adj, er  >> %vbsf_ebur128%
ECHO 'Set objStdOut = WScript.StdOut  >> %vbsf_ebur128%
ECHO Set objFSO = CreateObject("Scripting.FileSystemObject") >> %vbsf_ebur128%
ECHO Set objFile = objFSO.OpenTextFile("!ebur128File!", ForReading) >> %vbsf_ebur128%
ECHO er = 1 >> %vbsf_ebur128%
ECHO v = 0 >> %vbsf_ebur128%
ECHO adj = 0 >> %vbsf_ebur128%
ECHO Do Until objFile.AtEndOfStream >> %vbsf_ebur128%
ECHO    line = lcase(objFile.ReadLine) >> %vbsf_ebur128%
ECHO    if instr(line,lcase("Integrated loudness:")) > 0 then >> %vbsf_ebur128%
ECHO       line = lcase(objFile.ReadLine) >> %vbsf_ebur128%
ECHO       s = instr(line,lcase("I:")) + 2 >> %vbsf_ebur128%
ECHO       e = instr(line,lcase("LUFS")) - 1 >> %vbsf_ebur128%
ECHO       'WScript.StdOut.WriteLine "line=" ^& line >> %vbsf_ebur128%
ECHO       'WScript.StdOut.WriteLine s ^& " " ^& e  >> %vbsf_ebur128%
ECHO       if s^<=0 or e^<=0 then  >> %vbsf_ebur128%
ECHO          exit do >> %vbsf_ebur128%
ECHO       end if >> %vbsf_ebur128%
ECHO       v = trim(mid(line,s,e-s+1)) >> %vbsf_ebur128%
ECHO       'WScript.StdOut.WriteLine "string v=" ^& v >> %vbsf_ebur128%
ECHO       v = cdbl(v) >> %vbsf_ebur128%
ECHO       'WScript.StdOut.WriteLine "cdbl v=" ^& v >> %vbsf_ebur128%
ECHO       v = -23 - v >> %vbsf_ebur128%
ECHO       'WScript.StdOut.WriteLine "-23-v v=" ^& v >> %vbsf_ebur128%
ECHO       adj = min(abs(max(v,0)),16) >> %vbsf_ebur128%
ECHO       'WScript.StdOut.WriteLine "adj=" ^& adj >> %vbsf_ebur128%
ECHO       er = 0 >> %vbsf_ebur128%
ECHO       exit do >> %vbsf_ebur128%
ECHO    end if >> %vbsf_ebur128%
ECHO Loop >> %vbsf_ebur128%
ECHO WScript.StdOut.WriteLine adj >> %vbsf_ebur128%
ECHO objFile.Close >> %vbsf_ebur128%
ECHO set objFile = nothing >> %vbsf_ebur128%
ECHO set objFSO = nothing >> %vbsf_ebur128%
ECHO wscript.quit(er) ' 1=error. 0=ok >> %vbsf_ebur128%
ECHO function Max(a,b) >> %vbsf_ebur128%
ECHO     Max = a >> %vbsf_ebur128%
ECHO     If b ^> a then Max = b >> %vbsf_ebur128%
ECHO end function >> %vbsf_ebur128%
ECHO function Min(a,b) >> %vbsf_ebur128%
ECHO     Min = a >> %vbsf_ebur128%
ECHO     If b ^< a then Min = b >> %vbsf_ebur128%
ECHO end function  >> %vbsf_ebur128%
for /f "tokens=*" %%i in ('cscript //B //NOLOGO %vbsf_ebur128%') do set adjLUFS=%%i
ECHO The value adjLUFS=!adjLUFS!

pause
exit

Last edited by hydra3333; 24th December 2013 at 22:40. Reason: update text: adjLUFS= min(abs(max(-23-VLUFS,0)),16)
hydra3333 is offline   Reply With Quote
Old 22nd December 2013, 11:45   #2  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,915
Quote:
Originally Posted by hydra3333 View Post
...
adjVOLM=min(abs(VOLI),16)
adjLUFS= min(abs(max(-23-VLUFS),0)),16)
...
I'm not really sure whether to use the LUFS number or the max loudness number from "-af volumedetect". Which is "best" pragmatically?
Reading:
http://www.ffmpeg.org/ffmpeg-filters.html#toc-volumedetect
http://www.ffmpeg.org/ffmpeg-filters.html#toc-ebur128
http://tech.ebu.ch/loudness

you can use:
adjVOL=min(adjVOLM,adjLUFS)
because you can never amplify more than adjVOLM without clip and more than adjLUFS to avoid high volume.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline   Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 00:55.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.