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

如何用FFmpeg实现4个不同时长视频的分屏顺序播放拼接?

用FFmpeg实现按顺序播放的横向分屏视频

核心思路

先为每个视频生成对应时间线的流:播放前显示首帧、播放时段正常播放、播放结束后显示末帧,最后用hstack将四个480x1080的流拼成1920x1080的分屏,音频按顺序拼接(非播放时段静音)。

准备工作

  1. 四个视频文件:命名为1.mp4、2.mp4、3.mp4、4.mp4(分辨率480x1080带音频)
  2. 各视频的首帧/末帧截图:命名规则如2_first.jpg(视频2首帧)、2_last.jpg(视频2末帧),分辨率需与视频一致(480x1080)

Shell脚本实现

将以下内容保存为split_screen.sh,赋予执行权限后运行:

#!/bin/bash

# 定义各视频时长(单位:秒)
t1=60   # 1.mp4时长
t2=95   # 2.mp4时长
t3=80   # 3.mp4时长
t4=65   # 4.mp4时长

# 计算总时长及各视频结束时间点
total=$((t1 + t2 + t3 + t4))
t1_end=$t1
t2_end=$((t1 + t2))
t3_end=$((t2_end + t3))

# FFmpeg命令
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 \
-loop 1 -i 1_last.jpg \
-loop 1 -i 2_first.jpg -loop 1 -i 2_last.jpg \
-loop 1 -i 3_first.jpg -loop 1 -i 3_last.jpg \
-loop 1 -i 4_first.jpg \
-filter_complex "
# 处理视频1:播放60秒,之后显示末帧至总时长
[0:v] trim=0:$t1, setpts=PTS-STARTPTS [v1_main];
[4:v] trim=0:$((total - t1)), setpts=PTS-STARTPTS [v1_post];
[v1_main][v1_post] concat=n=2:v=1:a=0 [v1];

# 处理视频2:前60秒显示首帧,播放95秒,之后显示末帧至总时长
[5:v] trim=0:$t1, setpts=PTS-STARTPTS [v2_pre];
[1:v] trim=0:$t2, setpts=PTS-STARTPTS [v2_main];
[6:v] trim=0:$((total - t1_end)), setpts=PTS-STARTPTS [v2_post];
[v2_pre][v2_main][v2_post] concat=n=3:v=1:a=0 [v2];

# 处理视频3:前155秒显示首帧,播放80秒,之后显示末帧至总时长
[7:v] trim=0:$t2_end, setpts=PTS-STARTPTS [v3_pre];
[2:v] trim=0:$t3, setpts=PTS-STARTPTS [v3_main];
[8:v] trim=0:$((total - t3_end)), setpts=PTS-STARTPTS [v3_post];
[v3_pre][v3_main][v3_post] concat=n=3:v=1:a=0 [v3];

# 处理视频4:前235秒显示首帧,播放65秒至结束
[9:v] trim=0:$t3_end, setpts=PTS-STARTPTS [v4_pre];
[3:v] trim=0:$t4, setpts=PTS-STARTPTS [v4_main];
[v4_pre][v4_main] concat=n=2:v=1:a=0 [v4];

# 横向拼接四个视频流
[v1][v2][v3][v4] hstack=n=4:shortest=0 [v_out];

# 处理音频:顺序播放,非播放时段静音
[0:a] atrim=0:$t1, asetpts=PTS-STARTPTS [a1_main];
anullsrc=channel_layout=stereo:sample_rate=44100, trim=0:$((total - t1)) [a1_post];
[a1_main][a1_post] concat=n=2:v=0:a=1 [a1];

anullsrc=channel_layout=stereo:sample_rate=44100, trim=0:$t1 [a2_pre];
[1:a] atrim=0:$t2, asetpts=PTS-STARTPTS [a2_main];
anullsrc=channel_layout=stereo:sample_rate=44100, trim=0:$((total - t1_end)) [a2_post];
[a2_pre][a2_main][a2_post] concat=n=3:v=0:a=1 [a2];

anullsrc=channel_layout=stereo:sample_rate=44100, trim=0:$t2_end [a3_pre];
[2:a] atrim=0:$t3, asetpts=PTS-STARTPTS [a3_main];
anullsrc=channel_layout=stereo:sample_rate=44100, trim=0:$((total - t3_end)) [a3_post];
[a3_pre][a3_main][a3_post] concat=n=3:v=0:a=1 [a3];

anullsrc=channel_layout=stereo:sample_rate=44100, trim=0:$t3_end [a4_pre];
[3:a] atrim=0:$t4, asetpts=PTS-STARTPTS [a4_main];
[a4_pre][a4_main] concat=n=2:v=0:a=1 [a4];

# 混合所有音频流
[a1][a2][a3][a4] amix=inputs=4:duration=longest [a_out]
" \
-c:v libx264 -c:a aac -threads auto output.mp4

关键参数说明

  • -loop 1:让图片循环播放,用于填充非播放时段
  • trim:截取视频/音频的指定时段
  • setpts/asetpts:重置时间戳,避免拼接后出现跳帧
  • concat:将多个视频/音频流按顺序拼接
  • hstack=n=4:横向拼接4个视频流,自动适配1920x1080分辨率
  • amix:混合多个音频流,实现顺序播放效果(非播放时段为静音,不影响正常音频)

注意事项

  • 若图片分辨率与视频不一致,需在图片流后添加scale=480:1080滤镜
  • 若原音频的声道/采样率不一致,需用aresample统一参数(比如在anullsrc中匹配原音频参数)
  • 可根据实际时长修改脚本中的t1至t4数值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:20:29