Search code examples
ffmpegvideo-editing

Partial SPLIT screen video using ffmpeg?


  • I would like to show you an actual example so that you guys can understand what I am trying to achieve

  • I have a VIDEO that is entirely split screen currently

  • If you observe carefully, at the beginning of this video, there are cutscenes that are the same for everyone enter image description here

  • After that the actual split screen content begins which each screen has something different going on enter image description here

  • Notice how we are back to the same cutscene type content around 10:55 and 29:05

  • Basically whenever there is a cut scene I would like to show it without split screen from a single source

  • Whenever it is not a cut scene, I want it to be a split screen video

  • Let us say that 00:00 to 01:15 and 10:00 to 10:30 and 29:00 to end of the video has cutscenes

  • These 3 parts need to be shown without split screen while the rest of the video shows up as split screen

  • How do I achieve this in ffmpeg?

  • I wrote a script that does the split screen part

ffmpeg -i "$player_one.$player_one_extension" \
    -i "$player_two.$player_two_extension" \
    -i "$player_three.$player_three_extension" \
    -i "$player_four.$player_four_extension" \
    -filter_complex \
        "nullsrc=size=${video_width}x${video_height} [base]; \
        [0:v] trim=start=$player_one_offset,setpts=PTS-STARTPTS, scale=${half_width}x${half_height}, drawtext=fontfile=control-freak-font/CONTF___.ttf:text='${player_one_name}':fontsize=$font_size:fontcolor=0xFFFFFF:alpha='$alpha':x=w-text_w-${font_padding}:y=h-text_h-${font_padding} [upperleft]; \
        [1:v] trim=start=$player_two_offset,setpts=PTS-STARTPTS, scale=${half_width}x${half_height}, drawtext=fontfile=control-freak-font/CONTF___.ttf:text='${player_two_name}':fontsize=$font_size:fontcolor=0xFFFFFF:alpha='$alpha':x=w-text_w-${font_padding}:y=h-text_h-${font_padding} [upperright]; \
        [2:v] trim=start=$player_three_offset,setpts=PTS-STARTPTS, scale=${half_width}x${half_height}, drawtext=fontfile=control-freak-font/CONTF___.ttf:text='${player_three_name}':fontsize=$font_size:fontcolor=0xFFFFFF:alpha='$alpha':x=w-text_w-${font_padding}:y=h-text_h-${font_padding} [lowerleft]; \
        [3:v] trim=start=$player_four_offset,setpts=PTS-STARTPTS, scale=${half_width}x${half_height}, drawtext=fontfile=control-freak-font/CONTF___.ttf:text='${player_four_name}':fontsize=$font_size:fontcolor=0xFFFFFF:alpha='$alpha':x=w-text_w-${font_padding}:y=h-text_h-${font_padding} [lowerright]; \
        [3:a] atrim=start=$audio_offset,asetpts=PTS-STARTPTS[outa]; [base][upperleft] overlay=shortest=1 [tmp1]; [tmp1][upperright] overlay=shortest=1:x=${half_width} [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=${half_height} [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=${half_width}:y=${half_height}[v]"\
    -map "[v]" -map "[outa]" -c:v libx264 -shortest -t $duration "100_100_hardcore_ghost_recon_future_soldier_coop_pc_${mission}4k.mp4"

  • The way I understand the code above has a split base for the entire duration of the video
  • One way that I could think of is to make individual videos separately. For example, the cutscenes from 00:00 to 01:15, 10:00 to 10:30 and 29:00 to end would be 3 separate videos. Remaining would be split screen videos and then I would have to merge all the 5 clips together using ffmpeg concat. Is there a better way?

Solution

  • overlay with enable option

    ffmpeg -hide_banner \
    -i test03.mkv \
    -ss 2 -i test06.mkv \
    -ss 4 -i test10.mkv \
    -ss 6 -i test14.mkv -filter_complex "
    nullsrc=size=1920x1080[b];
    [0][b]scale2ref=iw/2:ih/2[v0][b];
    [1][b]scale2ref=iw/2:ih/2[v1][b];
    [2][b]scale2ref=iw/2:ih/2[v2][b];
    [3][b]scale2ref=iw/2:ih/2[v3][b];
    [b][v0]overlay=shortest=1[b];
    [b][v1]overlay=x=W/2[b];
    [b][v2]overlay=y=H/2[b];
    [b][v3]overlay=y=H/2:x=W/2[b];
    [b][0]overlay=enable='lt(t,2)+between(t,3,5)+between(t,7,9)'[v]
    " -map "[v]" -map 3:a -c:v h264 -c:a copy -y /tmp/output.mp4
    

    used -ss instead trim filter, scale2ref instead scale. Change size of background nullsrc