Log in

View Full Version : ffmpeg concurrent processing with drag and drop


FranceBB
5th January 2018, 07:05
Hi,
I made a simple script for my colleagues to encode files using ffmpeg.
They didn't like the idea of learning Avisynth nor the fact that they had to manually insert the name and the path of the file in the .bat.
They asked a drag and drop solution and I made one.


@echo off
setlocal disableDelayedExpansion
::
:: first assume normal call, get args from %*
set args=%*
set "dragDrop="
::
:: Now check if drag&drop situation by looking for %0 in !cmdcmdline!
:: if found then set drag&drop flag and get args from !cmdcmdline!
setlocal enableDelayedExpansion
set "cmd=!cmdcmdline!"
set "cmd2=!cmd:*%~f0=!"
if "!cmd2!" neq "!cmd!" (
set dragDrop=1
set "args=!cmd2:~0,-1! "
set "args=!args:* =!"
)
::
:: Process the first argument only
for %%F in (!args!) do (
if "!!"=="" endlocal & set "dragDrop=%dragDrop%"
rem ------------------------------------------------
rem - Your file processing starts here.
rem
rem Change to drive and directory of input file
%%~dF
cd %%~pF
C:\Encoding\ffmpeg.exe -i "%%~nxF" -pix_fmt yuv422p -vcodec mpeg2video -s 1920:1080 -aspect 16:9 -vf setfield=tff -flags +ildct+ilme -r 25 -b:v 50000k -minrate 50000k -maxrate 50000k -bufsize 36408333 -acodec pcm_s16le -ar 48000 -g 12 -bf 2 -profile:v 0 -level:v 2 -color_range 1 -color_primaries 1 -color_trc 1 -colorspace 1 -f mxf "C:\Encoding\%%~nF encoded.mxf"
rem
rem - Your file processing ends here
rem -------------------------------------------------
)
if defined dragDrop (
pause
exit
)


However, our machines have many cores and thread (we have two Intel Xeon E5 2630 v3 on each machine: 16 core, 32 thread), but the MPEG-2 encoder in ffmpeg is single thread, so I would like to modify the bat above to process multiple files at a time.

smok3
5th January 2018, 11:23
On Linux I'd use gnu parallel or bash something up (https://github.com/brontosaurusrex/stretchbang/blob/master/.experiments/bin/unidirectionalDirParallelEncoderModel).

maybe something like https://github.com/mmstick/parallel
or powershell https://blogs.technet.microsoft.com/uktechnet/2016/06/20/parallel-processing-with-powershell/

raffriff42
5th January 2018, 15:19
Launch new processes? (untested; will generate new command windows so try to limit their number) for %%F in (!args!) do (
if "!!"=="" endlocal & set "dragDrop=%dragDrop%"
start (https://ss64.com/nt/start.html) t1.bat "%%~dpnxF"
)

t1.bat:rem Change to drive and directory of input file
%~d1
cd %~p1
C:\Encoding\ffmpeg.exe -i "%~nx1" ^
-pix_fmt yuv422p -vcodec mpeg2video -s 1920:1080 -aspect 16:9 ^
-vf setfield=tff -flags +ildct+ilme -r 25 -b:v 50000k ^
-minrate 50000k -maxrate 50000k -bufsize 36408333 ^
-acodec pcm_s16le -ar 48000 ^
-g 12 -bf 2 -profile:v 0 -level:v 2 ^
-color_range 1 -color_primaries 1 -color_trc 1 -colorspace 1 ^
-f mxf "C:\Encoding\%~n1 encoded.mxf"

Phanton_13
5th January 2018, 17:23
This quick and dirty code is for two processes and it works but with the limitation that you need the same executable with various names for it to work, this also work as drag an drop bat file

@echo Off
echo EXECUTING BATCH

:PROCESS1
tasklist /fi "imagename eq opusenc-1.exe" |find ":" > nul
if errorlevel 1 goto PROCESS2
goto EXECUTE_PROCESS1

:PROCESS2
tasklist /fi "imagename eq opusenc-2.exe" |find ":" > nul
if errorlevel 1 goto WAITER
goto EXECUTE_PROCESS2


:WAITER
:: wait 10 seconds
PING localhost -n 11 >NUL
goto PROCESS1

:EXECUTE_PROCESS1
if (%1)==() goto OUT
start "opusenc-1" C:\Users\User\Desktop\sox\opusenc-1.exe --vbr --comp 10 --bitrate 32 %1 "%~n1[32kbps].opus"
shift
goto PROCESS1

:EXECUTE_PROCESS2
if (%1)==() goto OUT
start "opusenc-2" C:\Users\User\Desktop\sox\opusenc-2.exe --vbr --comp 10 --bitrate 32 %1 %~n1[32kbps].opus"
shift
goto PROCESS2

:OUT
EXIT

Alternative with one executable but it has the limitation that you ned to generate a window and canot execute the comands is second plane.

@echo Off
echo EXECUTING BATCH

:PROCESS1
tasklist /fi "WINDOWTITLE eq opusenc-1" |find ":" > nul
if errorlevel 1 goto PROCESS2
goto EXECUTE_PROCESS1

:PROCESS2
tasklist /fi "WINDOWTITLE eq opusenc-2" |find ":" > nul
if errorlevel 1 goto WAITER
goto EXECUTE_PROCESS2


:WAITER
:: wait 10 seconds
PING localhost -n 11 >NUL
goto PROCESS1

:EXECUTE_PROCESS1
if (%1)==() goto OUT
start "opusenc-1" C:\Users\User\Desktop\sox\opusenc.exe --vbr --comp 10 --bitrate 32 %1 "%~n1[32kbps].opus"
shift
goto PROCESS1

:EXECUTE_PROCESS2
if (%1)==() goto OUT
start "opusenc-2" C:\Users\User\Desktop\sox\opusenc.exe --vbr --comp 10 --bitrate 32 %1 %~n1[32kbps].opus"
shift
goto PROCESS2

:OUT
EXIT

I you want is possible to start the program minimized using /MIN and in low priority with /LOW like this:
start "APP" /LOW /MIN app.exe arguments