合并不同格式的视频

合并不同格式的视频

我收集了一些使用各种不同设备和编解码器录制和编码的视频。我尝试用它们制作一部电影。我认为将它们全部转换为相同格式是个好主意,因此我对所有视频运行以下命令

ffmpeg -i "${input}" -c:v libx264 -c:a aac "${output}"

然后,将文件名放入列表中后,我尝试使用 concat demuxer

ffmpeg -f concat -safe 0 -i list.txt -c copy "${output}"

(我也尝试使用与上述相同的编解码器再次重新编码,但结果是一样的。)

但这个过程会出现很多错误 [1],输出的视频会来回跳动。在找出所有错误的原因之前,有没有更好的方法来合并不同来源、不同年代、不同编解码器、不同一切的不同视频?

[1] 错误很多,例如:

[mp4 @ 0x5588e448ec80] Non-monotonous DTS in output stream 0:1; previous: 1192126, current: 1160221; changing to 1192127. This may result in incorrect timestamps in the output file.
[h264 @ 0x5588e44d0b80] Reference 6 >= 4
[h264 @ 0x5588e44d0b80] error while decoding MB 53 1, bytestream 6271

答案1

#!/bin/bash
WID=1280
HEI=720
# WID="$(ffprobe -v error -show_entries stream=width -of default=noprint_wrappers=1:nokey=1 "$f")"
# HEI="$(ffprobe -v error -show_entries stream=height -of default=noprint_wrappers=1:nokey=1 "$f")"
INP=()
FCT=-1
PAD=""
FIL=""
for f in *.mp4; do
  echo $f
  INP+=("-i")
  INP+=("$f")
  ((FCT+=1))
  s="[${FCT}v0]"
  PAD+="[${FCT}:v:0]pad=${WID}:${HEI}:(ow-iw)/2:(oh-ih)/2${s};"
  FIL+="${s}[${FCT}:a:0]"
done
((FCT+=1))
ffmpeg -hide_banner "${INP[@]}" -filter_complex "${PAD}${FIL}concat=n=${FCT}:v=1:a=1[v][a]" -map [v] -map [a] -c:v h264_nvenc -cq 23 -c:a aac -y output.mkv

它工作得不太好,需要做很多改进。主要工作是填充黑色空间以使所有视频获得相同的分辨率。

怎么运行的:

  1. 找到视频的最大宽度和高度,将变量 WID=1280 和 HEI=720 替换为您的分辨率值
  2. 用你的扩展名或表达式替换 *.mp4
  3. 更改编解码器
  4. 在带有视频的目录中运行脚本,脚本将生成字符串,如下所示:

ffmpeg -i "输入 1.mp4" -i "输入 2.mp4" -filter_complex [0:v:0]pad=1280:720:(ow-iw)/2:(oh-ih)/2[0v0];[1:v:0]pad=1280:720:(ow-iw)/2:(oh-ih)/2[1v0];[0v0][0:a:0][1v0][1:a:0]concat=n=2:v=1:a=1[v][a]" -map [v] -map [a] -c:v h264_nvenc -cq 23 -c:a aac -y 输出.mkv

并运行它。过滤序列的每个部分都带有 pad:

[0:v:0]pad=1280:720:(ow-iw)/2:(oh-ih)/2[0v0];

将会填充视频周围的空白区域以对齐分辨率。

相关内容