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
- Input Files: We list all 9 video files as inputs (3 for Area1, 2 for each of the other areas).
- Base Streams: Each area gets a 320x240 blank stream matching the total output duration (4 seconds) to fill gaps between clips.
- 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).
- Overlay for Areas: Clips are layered onto their area's base stream with
shortest=0to ensure the final area stream matches the full 4-second duration (instead of being cut short by the last clip). - 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
trimfilter for that clip. - Adjust the
durationinnullsrcif your longest segment is longer than 4 seconds. - If you want a custom color for the blank gaps instead of black, add
color=your_colorto thenullsrc(e.g.,nullsrc=size=320x240:duration=4:color=gray).
内容的提问来源于stack exchange,提问作者Robert Smith
相关产品推荐
相关产品推荐

