hydra3333
22nd December 2013, 08:44
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:
".\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
[Parsed_volumedetect_0 @ 049ae8a0] max_volume: -7.7 dB
in this case into VOLM=-7.7
and
I: -25.1 LUFS
in this case into VLUFS=-25.1
and then, in DOS, calculate
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
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.
@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
Can someone suggestion a simpler way to do it than below ?
So...
the outputs from these look interesting:
".\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
[Parsed_volumedetect_0 @ 049ae8a0] max_volume: -7.7 dB
in this case into VOLM=-7.7
and
I: -25.1 LUFS
in this case into VLUFS=-25.1
and then, in DOS, calculate
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
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.
@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