Roman Stadler
Roman Stadler

Reputation: 35

How to make a batch file wait for all processes of another call to finish before continuing

The idea of this script is to take a (lecture) video, split it into smaller pieces, remove the silence for each one, and merge them back together, for increased performance, since the silence-removing script does not scale that well for larger videos.

The 3 batch scripts below work perfectly when started manually after eachother, but when trying to launch them from a single .bat file, I can't prevent them from starting at the same time, which creates errors at the merging stage.

These are the 3 batch files:

  1. split.bat
  2. startall.bat
  3. merge.bat

Split.bat creates 10 minute long segments, afterwards, startall.bat starts one Video-Remove-Silence task for every segment. At the end, merge.bat creates one single mp4 file with all the segments.

split.bat does the following:

ffmpeg -i in.mp4 -c copy -map 0 -segment_time 00:10:00 -f segment out%%03d.mp4
exit

startall.bat:

start start000.bat
start start001.bat
start start002.bat
start start003.bat
...

The start000.bat call looks like this:

python video-remove-silence out000.mp4 --linear 0.0005
exit

And merge.bat:

:: Create File List
for %%i in (*_result.mp4) do echo file '%%i'>> mylist.txt
:: Concatenate Files
ffmpeg -f concat -safe 0 -i mylist.txt -c copy shortened.mp4

del "C:\Users\Roman\Desktop\download\mylist.txt"
del "C:\Users\Roman\Desktop\download\out*.mp4"
exit

When trying either call, or start /wait, errors occur due to simultaneous execution:

START /wait split.bat
START /wait startall2.bat
START /wait merge.bat

So basically my question is, how can I call these 3 scripts and prevent merge.bat from starting, until all processes inside startall.bat have finished?

Upvotes: 1

Views: 3276

Answers (2)

Compo
Compo

Reputation: 38613

Despite the fact that you said you'd done this using call already, I do not believe that doing so should have caused you the issue you're reporting. You should have used Call everywhere you'd used start, and removed the exit from the end of each, (you could also change those to exit /b or goto :EOF if needed):


split.bat:

@ffmpeg -i in.mp4 -c copy -map 0 -segment_time 00:10:00 -f segment out%%03d.mp4

startall.bat:

@Call start000.bat
@Call start001.bat
@Call start002.bat
@Call start003.bat
...

The start000.bat call looks like this:

@python video-remove-silence out000.mp4 --linear 0.0005

merge.bat:

@Rem Create File List
@(For %%I In (*_result.mp4) Do @Echo file '%%I') > mylist.txt
@Rem Concatenate Files
@ffmpeg -f concat -safe 0 -i mylist.txt -c copy shortened.mp4
@Del /Q out*.mp4 mylist.txt

Execution:

@Call split.bat
@Call startall2.bat
@Call merge.bat

Upvotes: 1

Aacini
Aacini

Reputation: 67216

You may use the method stated at this answer, that is, your main Batch file could be this one:

rem Split:
call split.bat

rem Start all and wait for all to terminate
(
start start000.bat
start start001.bat
start start002.bat
start start003.bat
...
) | pause

rem Merge:
call merge.bat

Upvotes: 4

Related Questions