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

合并3个视频并匹配主视频帧率:脚本故障排查求助

视频拼接脚本问题排查与修复

有三个MP4视频:开场视频(sting.mp4)、主视频(mezzfile.mp4)、结尾视频(endboard.mp4),仅主视频帧率与另外两个不同,其余参数一致。尝试用ffprobe获取主视频帧率并统一输出帧率,但编写的bash脚本无法正常运行,原脚本如下:

#!/bin/bash

mezzfile=mezzfile.mp4
tailtime=20
duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $mezzfile)
framerate=$(ffprobe -v 0 -of compact=p=0 -select_streams 0 \
-show_entries stream=r_frame_rate '$mezzfile')

ffmpeg -hide_banner -y \
  -i sting.mp4 \
  -i $mezzfile \
  -i endboard.mp4 \
  -filter_complex \
    "[0:v]setpts=PTS-STARTPTS,fps=${framerate}[v_intro]; \
     [0:a]asetpts=PTS-STARTPTS,fps=${framerate}[a_intro]; \
     [1:v]setpts=PTS-STARTPTS,split[v_main1][v_main2]; \
     [1:a]asetpts=PTS-STARTPTS[a_main]; \
     [2:v]setpts=PTS-STARTPTS,fps=${framerate}[v_endboard]; \
     [v_main1]select='gt(t,$duration-$tailtime)',scale=w=iw/2:h=ih/2,setpts=PTS-STARTPTS[v_tail]; \
     [v_endboard][v_tail]overlay[v_pip]; \
     [v_main2]select='lte(t,$duration-$tailtime)',setpts=PTS-STARTPTS[v_mid]; \
     [v_intro][v_mid][v_pip]concat=n=3:v=1:a=0[v_out]; \
     [a_intro][a_main]concat=n=2:v=0:a=1[a_out]" \
  -map "[v_out]" \
  -map "[a_out]" \
  output.mp4

问题分析

  • ffprobe变量解析错误:获取帧率的命令中,'$mezzfile'用单引号包裹,导致bash无法解析变量,会把$mezzfile当作字符串直接传入ffprobe,找不到目标文件。
  • 音频滤镜误用参数:音频流不存在帧率(fps)属性,[0:a]滤镜链中的fps是视频专属滤镜,应用在音频上会直接导致ffmpeg报错。
  • 浮点数运算失败:duration是ffprobe返回的浮点数(如125.8),bash默认仅支持整数算术运算,$duration-$tailtime会触发计算错误。
  • concat参数不统一:concat滤镜要求所有输入视频流的分辨率、帧率、像素格式完全一致,原脚本未明确强制主视频流的帧率属性,存在兼容隐患。

修复后的脚本

#!/bin/bash

mezzfile=mezzfile.mp4
tailtime=20

# 获取主视频帧率(修正变量引用,明确指定视频流)
framerate=$(ffprobe -v error -of compact=p=0 -select_streams v:0 -show_entries stream=r_frame_rate "$mezzfile")

# 获取主视频时长(保留浮点数格式)
duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$mezzfile")

# 用bc处理浮点数减法,计算截断时间点
cutoff_time=$(echo "$duration - $tailtime" | bc)

ffmpeg -hide_banner -y \
  -i sting.mp4 \
  -i "$mezzfile" \
  -i endboard.mp4 \
  -filter_complex \
    "[0:v]setpts=PTS-STARTPTS,fps=$framerate[v_intro]; \
     [0:a]asetpts=PTS-STARTPTS[a_intro]; \
     [1:v]setpts=PTS-STARTPTS,fps=$framerate,split[v_main1][v_main2]; \
     [1:a]asetpts=PTS-STARTPTS[a_main]; \
     [2:v]setpts=PTS-STARTPTS,fps=$framerate[v_endboard]; \
     [v_main1]select='gt(t,$cutoff_time)',scale=w=iw/2:h=ih/2,setpts=PTS-STARTPTS[v_tail]; \
     [v_endboard][v_tail]overlay[v_pip]; \
     [v_main2]select='lte(t,$cutoff_time)',setpts=PTS-STARTPTS[v_mid]; \
     [v_intro][v_mid][v_pip]concat=n=3:v=1:a=0[v_out]; \
     [a_intro][a_main]concat=n=2:v=0:a=1[a_out]" \
  -map "[v_out]" \
  -map "[a_out]" \
  -r "$framerate" \
  output.mp4

修复说明

  1. 修正ffprobe的变量引用,将'$mezzfile'改为"$mezzfile",同时用select_streams v:0明确指定读取视频流,避免误选音频流导致的帧率获取错误。
  2. 移除音频滤镜中的fps参数,音频仅需调整时间基准(asetpts)即可同步。
  3. 使用bc工具处理浮点数减法,解决bash无法计算小数的问题,得到准确的截断时间点。
  4. 为主视频流添加fps=$framerate滤镜,确保concat的所有视频流帧率统一;输出时添加-r "$framerate"参数,强制指定输出文件的帧率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:50:29