您的输入参数有所不同(这很糟糕)

您的输入参数有所不同(这很糟糕)

我有一个 YouTube 视频,想为其添加 30 秒的片头和片尾。这三个文件保存为 MP4。我使用的是 macOS。

按照说明进行操作这个官方的 FFmpeg 页面我使用这些命令将文件转换为 ts 文件并进行了测试。它们全部有效。

ffmpeg -i intro.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts in.ts

但是当我使用以下命令时:

/opt/local/bin/ffmpeg -f mpegts -i "concat:intro.ts|episode1.ts|out.ts" -c copy -bsf:a aac_adtstoasc output.mp4

output.mp4已损坏:第一个视频显示正确,但似乎没有视觉信息(音频正常且output.mp4长度符合预期)。当我使用在同一个应用程序中创建的视频时,这种方法有效,所以我怀疑这就是问题所在:一个文件是在 iMovie 中创建的,一个文件是在 OBS 中创建的,另一个文件是先在 OBS 中创建的,然后从 YouTube 下载的。

请注意,所有 .TS 文件和output.mp4 在我的网站上以供审查。

真的想要的是这个。

  • 我想要一个可以转换 intro 和 outro 文件的命令,以便它们与剧集的属性相匹配,从而使连接起作用。
  • 然后,我想转换介绍文件以便它与结局的属性相匹配,以便于将来的录制。

答案1

您的输入参数有所不同(这很糟糕)

Input #0, mpegts, from 'intro.ts':
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 960x540 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 180k tbc
    Stream #0:1[0x101](eng): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 126 kb/s

Input #1, mpegts, from 'episode1.ts':
    Stream #1:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #1:1[0x101](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 123 kb/s

Input #2, mpegts, from 'out.ts':
    Stream #2:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #2:1[0x101](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 160 kb/s
  • intro.ts有 48000 音频采样率,但其他的有 44100。
  • episode1.ts具有 H.264 High profile,但其他的具有 Main profile。
  • intro.ts是960x540,但其他的是1280x720。
  • intro.ts帧速率和时间基准与其他的不同。

对于连接,输入需要具有相同的参数和相同数量和类型的流。

使所有输入相同

由于episode1.mp4是最长且最重要的输入,因此您可以使其他输入与之匹配。这需要对其他两个输入进行重新编码:

ffmpeg -i intro.mp4 -vf "scale=1280:-2,fps=30" -c:v libx264 -profile:v main -c:a aac -ar 44100 intro2.mp4
ffmpeg -i out.mp4 -c:v libx264 -profile:v main -c:a copy out2.mp4

由于可以使用 concat 解复用器,因此可以避免重新复用到 TS。因此,只需使用原始 MP4 输入即可。

康卡特

现在为 concat 解复用器创建一个文本文件:

file intro2.mp4
file episode1.mp4
file out2.mp4

然后使用 concat 解复用器进行连接:

ffmpeg -f concat -i input.txt -c copy output.mp4

-movflags +faststart如果要从服务器查看,您可以添加输出选项,以便可以更快地开始播放。

答案2

帖子 使用 ffmpeg 复制编解码器将 *.ts 文件合并为一个 mp4,包含一些连接文件的建议.ts(mp4 部分对您来说不感兴趣)。最令人惊讶的方法,如果视频具有相同的属性,甚至不使用 ffmpeg,因此您可以先尝试它,因为它很简单:

copy /b segment1_0_av.ts+segment2_0_av.ts+segment3_0_av.ts all.ts

如果这对你不起作用,帖子 如何使用 FFmpeg 连接两个 MP4 文件 提供了许多有用的信息。我在下面复制了 用户 rogerdpack 的回答 与您的问题最相关的内容(粗斜体文字是我强调的):

FFmpeg 有三种连接方法。

1.连接视频过滤器

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
  -filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] concat=n=3:v=1:a=1 [v] [a]" \
  -map "[v]" -map "[a]" output.mkv

请注意,此方法执行重新编码。

2.连接解复用器

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat -i mylist.txt -c copy output

对于 Windows

(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

3.concat 协议

ffmpeg -i "concat:input1|input2" -codec copy output

由于这些格式的性质以及此方法执行的简单连接,此方法不适用于许多格式,包括 MP4。

使用哪一个

  • 连接过滤器:如果您的输入不具有相同的参数(宽度、高度等),或者不是相同的格式/编解码器,或者您想要执行任何过滤,请使用此选项。(您可以只对不匹配的输入进行重新编码,以便它们共享相同的编解码器和其他参数,然后使用 concat 解复用器来避免对其他输入进行重新编码)。

  • 连接解复用器:当您想要避免重新编码并且您的格式不支持文件级别连接时使用(一般用户使用的大多数文件不支持文件级别连接)。

  • concat 协议:与支持文件级连接的格式(MPEG-1、MPEG-2 PS、DV)一起使用。请勿与 MP4 一起使用。

如果有疑问,请尝试 concat 解复用器。

您选择了 concat 协议解决方案,这显然是最有问题的。

我建议尝试其他两种方法。如果视频的属性不相同,则 concat 视频过滤器方法可能是最佳选择。否则,请尝试 concat demuxer 方法。

ffmpeg 文章 维基百科:连接 已经消失但仍存在于 Google Cache 中的数据提供了有关这三种方法的其他有用信息。它还强调了输入在属性上足够相似的重要性。

(由于我不是 ffmpeg 的用户,因此无法测试上述内容。无论如何,视频的属性对于该过程的可行性起着非常重要的作用。)

相关内容