You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FFmpeg实现4区域多视频分时段播放的技术问询

Solution for Multi-Area FFmpeg Video Playback with Timed Segments

Got it, let's solve both of your FFmpeg challenges step by step. The core idea is to first build a complete video stream for each area (with timed segments and gaps) then combine all four streams into the final 2x2 grid output.

Key Concepts to Use

  • trim: Crop individual video clips to exactly the duration they need to play.
  • setpts: Adjust the timestamp of each clip so it starts at the correct moment in the overall timeline.
  • nullsrc: Create a blank "base" stream for each area to fill gaps between clips.
  • overlay: Layer clips onto their area's base stream, then layer all four area streams onto the final output grid.

Full FFmpeg Command

First, make sure you include all your video files as inputs. Below is the command tailored to your exact segment timings (all times converted from milliseconds to seconds):

ffmpeg -i video1a.avi -i video1b.avi -i video1c.avi \
       -i video2a.avi -i video2b.avi \
       -i video3a.avi -i video3b.avi \
       -i video4a.avi -i video4b.avi \
       -filter_complex "
         # 1. Create final output base (640x480, 4 seconds total duration)
         nullsrc=size=640x480:duration=4 [base];

         # === Area 1: Top-left (320x240) ===
         nullsrc=size=320x240:duration=4 [a1_base];
         # video1a: plays 0-2s (2000ms)
         [0:v] scale=320x240, setpts=PTS-STARTPTS [v1a];
         # video1b: plays 2.5-3s (2500-3000ms, 0.5s duration)
         [1:v] scale=320x240, trim=duration=0.5, setpts=PTS-STARTPTS + 2.5/TB [v1b];
         # video1c: plays 3-4s (3000-4000ms, 1s duration)
         [2:v] scale=320x240, trim=duration=1, setpts=PTS-STARTPTS + 3/TB [v1c];
         # Layer clips onto Area 1 base
         [a1_base][v1a] overlay=shortest=0 [a1_tmp1];
         [a1_tmp1][v1b] overlay=shortest=0 [a1_tmp2];
         [a1_tmp2][v1c] overlay=shortest=0 [area1];

         # === Area 2: Top-right (320x240) ===
         nullsrc=size=320x240:duration=4 [a2_base];
         # video2a: plays 0.3-0.4s (300-400ms, 0.1s duration)
         [3:v] scale=320x240, trim=duration=0.1, setpts=PTS-STARTPTS + 0.3/TB [v2a];
         # video2b: plays 0.8-0.9s (800-900ms, 0.1s duration)
         [4:v] scale=320x240, trim=duration=0.1, setpts=PTS-STARTPTS + 0.8/TB [v2b];
         # Layer clips onto Area 2 base
         [a2_base][v2a] overlay=shortest=0 [a2_tmp1];
         [a2_tmp1][v2b] overlay=shortest=0 [area2];

         # === Area 3: Bottom-left (320x240) ===
         nullsrc=size=320x240:duration=4 [a3_base];
         # video3a: plays 0.4-0.5s (400-500ms, 0.1s duration)
         [5:v] scale=320x240, trim=duration=0.1, setpts=PTS-STARTPTS + 0.4/TB [v3a];
         # video3b: plays 0.7-0.855s (700-855ms, 0.155s duration)
         [6:v] scale=320x240, trim=duration=0.155, setpts=PTS-STARTPTS + 0.7/TB [v3b];
         # Layer clips onto Area 3 base
         [a3_base][v3a] overlay=shortest=0 [a3_tmp1];
         [a3_tmp1][v3b] overlay=shortest=0 [area3];

         # === Area 4: Bottom-right (320x240) ===
         nullsrc=size=320x240:duration=4 [a4_base];
         # video4a: plays 0.4-0.5s (400-500ms, 0.1s duration)
         [7:v] scale=320x240, trim=duration=0.1, setpts=PTS-STARTPTS + 0.4/TB [v4a];
         # video4b: plays 0.8-0.9s (800-900ms, 0.1s duration)
         [8:v] scale=320x240, trim=duration=0.1, setpts=PTS-STARTPTS + 0.8/TB [v4b];
         # Layer clips onto Area 4 base
         [a4_base][v4a] overlay=shortest=0 [a4_tmp1];
         [a4_tmp1][v4b] overlay=shortest=0 [area4];

         # === Combine all four areas into final grid ===
         [base][area1] overlay=shortest=0 [tmp1];
         [tmp1][area2] overlay=shortest=0:x=320 [tmp2];
         [tmp2][area3] overlay=shortest=0:y=240 [tmp3];
         [tmp3][area4] overlay=shortest=0:x=320:y=240
       " -c:v libx264 output.mp4

Breakdown of Key Parts

  1. Input Files: We list all 9 video files as inputs (3 for Area1, 2 for each of the other areas).
  2. Base Streams: Each area gets a 320x240 blank stream matching the total output duration (4 seconds) to fill gaps between clips.
  3. Clip Processing:
    • scale=320x240: Resizes each clip to fit its area.
    • trim=duration=X: Ensures the clip only plays for exactly the needed time (e.g., 0.5s for video1b).
    • setpts=PTS-STARTPTS + Y/TB: Shifts the clip's start time to the correct moment in the overall timeline (Y is the start time in seconds).
  4. Overlay for Areas: Clips are layered onto their area's base stream with shortest=0 to ensure the final area stream matches the full 4-second duration (instead of being cut short by the last clip).
  5. Final Grid Overlay: Each area stream is placed in its 2x2 position (left/right, top/bottom) on the 640x480 final output.

Notes

  • If any of your source clips are exactly the duration you need, you can omit the trim filter for that clip.
  • Adjust the duration in nullsrc if your longest segment is longer than 4 seconds.
  • If you want a custom color for the blank gaps instead of black, add color=your_color to the nullsrc (e.g., nullsrc=size=320x240:duration=4:color=gray).

内容的提问来源于stack exchange,提问作者Robert Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:18:55