我有两个 *.mpg 文件。我想通过选择视频流 (MPEG-2) 和 MP2 音频流来连接它们。我的问题是这些流总是被重新编码。我想避免这种情况,但我尝试了好几个小时,都失败了。
输入文件:
Input #0, mpeg, from 'D:\a.mpg':
Duration: 01:25:54.05, start: 0.500000, bitrate: 4528 kb/s
Stream #0:0[0x1bf]: Data: dvd_nav_packet
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 192 kb/s
Stream #0:2[0x80]: Audio: ac3, 48000 Hz, stereo, fltp, 384 kb/s
Stream #0:3[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
Input #1, mpeg, from 'D:\b.mpg':
Duration: 00:12:53.11, start: 0.500000, bitrate: 4486 kb/s
Stream #1:0[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 192 kb/s
Stream #1:1[0x80]: Audio: ac3, 48000 Hz, stereo, fltp, 384 kb/s
Stream #1:2[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
FFmpeg 参数:(已尝试过多个参数之一)
-i "d:\a.mpg" -i "d:\b.mpg" -filter_complex "[0:3][0:1][1:2][1:0]concat=n=2:v=1:a=1[v][a]" -map [v] -map [a] "d:\c.mpg"
输出:
Stream mapping:
Stream #0:1 (mp2) -> concat:in0:a0
Stream #0:3 (mpeg2video) -> concat:in0:v0
Stream #1:0 (mp2) -> concat:in1:a0
Stream #1:2 (mpeg2video) -> concat:in1:v0
concat:out:v0 -> Stream #0:0 (mpeg1video)
concat:out:a0 -> Stream #0:1 (mp2)
如您所见,尽管应该只是复制流,但输出却是“mpeg1video”。但是,对于复杂的过滤器,指定“-c copy”是无效的。输出文件的“-f mpeg”和“-f dvd”也不起作用。后者确实创建了 MPEG-2 视频流,但它也会导致重新编码,尽管这不是必要的。
我确实知道“-f concat”输入格式,但我在尝试这种方式时遗漏了什么?我知道 FFmpeg 能够将 MPEG-2 视频和 MP2 音频复用到 .mpg 文件(PS 格式,不是 TS)中,因为如果我只是从 input.ts 重新复用到 output.mpg 并指定 -c copy,它就会按预期复制流。这表明,如果存在 MPEG-2 视频流、MP2 音频流并且目标文件扩展名是“.mpg”,它会自动使用正确的复用器而无需重新编码。但是,上述情况并非如此。
感谢您读到这里。
答案1
两件事:1)除非您明确将编解码器选项设置为copy
,否则 FFmpeg 将选择默认编码器,这意味着不会复制流。2)您显示的 ffmpeg 命令使用 concat筛选. 在流上使用过滤器需要那些流将被重新编码。这是因为过滤器作用于解码后的帧,而不是源中存在的编码帧。未经任何过滤器处理的流仍可复制。
在这里,您必须使用 concat demuxer,您曾表示您知道它。但为了完整起见...
#1创建一个文本文件,内容如下
file 'a.mpg'
file 'b.mpg'
#2康卡特
ffmpeg -f concat -i list.txt -c copy -map 0:v -map 0:a:0 c.mpg