A very simple approach is to just run each ffmpeg
process in the background, then wait for them to complete before going on to the next value of crf
.
for crf in 10 15 20 23 25 30 35 ; do
for vid_preset in medium slow veryslow; do
ffmpeg -r 25 -i pics/pic_%04d.png -vcodec libx264 \
-crf $crf -vpre $vid_preset anim_crf${crf}_${vid_preset}.mp4 &
done
wait
done
If you have parallel
installed, you can use it to run all 21 processes in a busy fashion.
# Run 4 jobs at a time, starting a new job whenever one completes.
parallel -j 4 ffmpeg -r 25 -i pics/pic_%04d.png \
-vcode libx264 -crf {1} -vpre {2} \
anim_crf{1}_{2}.mp4 ::: 10 15 20 23 25 30 35 ::: medium slow veryslow
{1}
is replaced by a choice from the first input source (following the first :::
), {2}
by a choice form the second input source. An example explains it more simply:
$ parallel echo {1} {2} ::: a b c :: 1 2
a 2
a 1
b 1
b 2
c 1
c 2
A messy approach in bash
4.3 or later (when wait -n
was introduced):
max_jobs=4
running=()
for c in 10 15 20 23 25 30 35; do
for v in medium slow veryslow; do
ffmpg ... &
running+=($!)
# If we're at capacity, wait for a job to complete
if (( ${#running[@]} == $max_jobs )); then
wait -n
# Any where from 0 to max_jobs - 1 could still be running
running=( $(jobs -p) )
fi
done
done