2

Video capture device cycling through 4 cameras every 4 seconds. Want to split the video into four streams to reduce the amount of key frames, save internet traffic and soothe the motion detector.

While the channel is inactive, there should be a still frame.

Created a test input file combined.mkv. Bash script to create it:

(
    set -e
    fontfile="/Windows/Fonts/arial.ttf"
    fontfile="/usr/share/fonts/TTF/DejaVuSans.ttf"
    i=0; for c in blue green magenta red; do ffmpeg -y -f lavfi -i color=s=640x480:d=35:r=25:c=$c \
        -vf "
            drawtext=fontfile=$fontfile: fontsize=160:fontcolor='white':text='$i':x=(w-text_w)/2:y=(h-line_h)/2,
            drawtext=fontfile=$fontfile: boxcolor=0x000000AA:box=1:fontsize=72:fontcolor='white':text='':timecode='00\:00\:00\:00':rate=25
        " \
        $i.mkv; i=$((i+1)); done

    ffmpeg -y -i 0.mkv -i 1.mkv -i 2.mkv -i 3.mkv -filter_complex "[0:v][1:v]overlay=enable='between(mod(t,16),4,8)'[o01];[o01][2:v]overlay=enable='between(mod(t,16),8,12)'[o012];[o012][3:v]overlay=enable='between(mod(t,16),12,16)'" combined.mkv

    rm -f 0.mkv 1.mkv 2.mkv 3.mkv
)

Extracting one channel at a time works fine: select filter extracts the frames belonging to the channel, then overlap filter is used to fill the gap at the beginning of the file:

mkdir -p desired
for i in 0 1 2 3; do
ffmpeg -y -f lavfi -i nullsrc=s=640x480:r=25 -i combined.mkv \
    -filter_complex "[1:v]select='between(mod(t*1000,16*1000),$i*4000+100,($i+1)*4000-100)'[selected$i];[0:v][selected$i]overlay=shortest=1" desired/split$i.mkv
done

But when I try to split and filter, I get garbage:

mkdir -p actual
ffmpeg -y -f lavfi -i nullsrc=s=640x480:r=25 -i combined.mkv \
    -filter_complex "[0:v]split=4[null0][null1][null2][null3];[1:v]split=4[in0][in1][in2][in3];
    [in0]select='between(mod(t*1000,16*1000),0*4000+100,(0+1)*4000-100)'[selected0];[null0][selected0]overlay=shortest=1[out0];
    [in1]select='between(mod(t*1000,16*1000),1*4000+100,(1+1)*4000-100)'[selected1];[null1][selected1]overlay=shortest=1[out1];
    [in2]select='between(mod(t*1000,16*1000),2*4000+100,(2+1)*4000-100)'[selected2];[null2][selected2]overlay=shortest=1[out2];
    [in3]select='between(mod(t*1000,16*1000),3*4000+100,(3+1)*4000-100)'[selected3];[null3][selected3]overlay=shortest=1[out3]
    " \
    -map '[out0]' actual/split0.mkv \
    -map '[out1]' actual/split1.mkv \
    -map '[out2]' actual/split2.mkv \
    -map '[out3]' actual/split3.mkv

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.