Is there a more efficient way to watermark and joi

2019-03-03 23:13发布

问题:

I have this batch file using ffmpeg to add a logo to my videos and then add an intro but it's taking anywhere from 10 hours to a day depending on how many I have to watermark, is there a more efficient way to achieve this? The videos sometimes have different resolutions so I can't remove the conversion to the 1280*720 size.

for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do ffmpeg.exe -y -i "%%I" -i white.png -filter_complex "[0:v]scale=iw:ih[v0];[1:v][v0]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1[v]" -map "[v]" -map 0:a -codec:v libx264 -preset ultrafast -crf 23 -codec:a copy "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"

for %%I in ("C:\Users\Administrator\Desktop\work\*.mp4") do ffmpeg -y -i %%I -c copy -vbsf h264_mp4toannexb -f mpegts -s 1280*720 %%I.ts && ffmpeg -y -i "concat:out1.ts|%%I.ts|out1.ts" -c:v libx264 -strict experimental -bsf:a aac_adtstoasc -ar 48000 -r 20 "C:\Users\Administrator\Desktop\Complete-videos\%%~nI.mp4"
pause

回答1:

Single command:

ffmpeg -i main.mp4 -i white.png -i out1.ts -filter_complex
  "[1][0]scale2ref=iw/6:ih/18[logo][0v];[0v][logo]overlay=W-w-3:H-h-1,scale=hd720[vid];
   [2][2:a][vid][0:a][2][2:a]concat=n=3:v=1:a=1[v][a]"
-map "[v]" -map "[a]" -r 20 -preset fast -ar 48000 out.mp4


回答2:

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
:: make a tempdir
:maketemp
SET "tempdir=%temp%\%random%"
IF EXIST "%tempdir%\" (GOTO maketemp) ELSE (MD "%tempdir%")

:: read each filename from source and process

for %%I in ("%sourcedir%\*.txt") DO (
  TITLE Processing %%I
  START "%%I" q43060025s "%%I"
  CALL :wait 10
)
CALL :wait 1
RD "%tempdir%"

GOTO :EOF

:: monitor number of files in temp directory and return if fewer than %1
:wait
:: wait 1 second
timeout /t 1 >NUL
FOR /f %%c IN ('dir /b /a-d "%tempdir%\*" 2^>nul ^| find /c /v "" ') DO IF %%c geq %1 GOTO wait
GOTO :eof

You would need to change the setting of sourcedir to suit your circumstances. I used some dummy .txt files for testing.

The time requirement is probably being caused because you are serially processing the files. The solution is to process the files in parallel, using the power of the multiple cores in modern PCs.

The idea here is to make a temporary directory to contain control files, then process each file using a sub-procedure batch (q43060025s.bat)

The sub-procedure inherits the calling procedure's environment, so tempdir will be established.

@ECHO OFF
SETLOCAL
:: do some operation on the filename passed as %1
title processing %~1
ECHO %time%>"%tempdir%\%~n1"
:: 4 to 21-second delay
SET /a delay=%RANDOM% %% 18 + 4
timeout /t %delay% >NUL
DEL "%tempdir%\%~n1"
CLS
exit

So - the subprocedure here is a dummy for demonstration. It uses tempdir and creates a file in that directory with the name of the file-to-be-processed containing something - I just used the time.

My sub-procedure simply then delays for 4 to 21 seconds, simulating some process with a variable processing time.

It then deletes the file it created and terminates.

Meanwhile, the main procedure is monitoring the number of files in the temporary directory, which is the number of sub-processes running. Simply count the files and if the count is greater than or equal to the parameter passed, then wait for 1 second and try again.

As the sub-procedure finishes its job, the count is reduced and the :wait routine will exit. The next file is selected, despatched to the sub-process and we wait again.

When the last file has been sent, we continue to wait until the count of sub-processes is zero (ie. less than 1) when we can delete the temporary directory.

So - all you need to do is construct your processing in place of the delay routine in q43060025s using the filename passed as %1 and your problem should be solved.