FFmpeg: объединение без перекодирования

1176

У меня есть два * .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 args: (один из многих пробовал)

-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», он автоматически использует правильный мультиплексор без перекодирования. Однако не в случае выше.

Спасибо за чтение до сих пор.

0

1 ответ на вопрос

1
Gyan

Две вещи: 1) если вы явно не установите опции кодека в copy, FFmpeg выберет кодировщик по умолчанию, что означает, что потоки не будут скопированы. 2) Показанная вами команда ffmpeg использует фильтр concat . Использование фильтра в потоке требует, чтобы эти потоки были перекодированы. Это потому, что фильтры работают с декодированными кадрами, а не с кодированными, присутствующими в источнике (ах). Потоки, которые не обрабатываются никаким фильтром, могут быть скопированы.

Здесь вам придется использовать демультиплексор concat, о котором вы уже знали. Но ради полноты ...

# 1 Создайте текстовый файл с надписью

file 'a.mpg' file 'b.mpg' 

# 2 Concat

ffmpeg -f concat -i list.txt -c copy -map 0:v -map 0:a:0 c.mpg 
Спасибо, Мульвя. Я понимаю частично. Я не уверен, почему кадры декодируются вообще. Фильтру concat не нужны декодированные кадры, потому что он просто объединяет потоки. Следовательно, впоследствии кодирование не требуется. Означает ли это, что каждый раз, когда используется сложный фильтр, FFmpeg декодирует кадры, чтобы передать их фильтру (фильтрам)? (хотя это и не обязательно) Thx для подсказок concat demuxer; Вот как я это сделал. Тем временем я использовал mkvmerge для объединения файлов. Работал. Хотя я все еще заинтересован в изучении этого на будущее. 7 лет назад 0
Большинство фильтров работают с растровыми изображениями или аудиосэмплами, так что это дизайн. Таким образом, даже если самому фильтру concat это не нужно, кадры все равно должны быть декодированы, потому что фильтры до или после в цепочке могут понадобиться. В первом случае необходимы декодированные кадры, а во втором - между фильтрами должен вызываться декодер, и, насколько я понимаю, это может не стоить того, если это даже возможно в текущей архитектуре. Только потоки, поданные где-то в комплексе фильтров, декодируются. Gyan 7 лет назад 0
Теперь я знаю, почему я мог попробовать все, чтобы избежать перекодирования. ;) Спасибо. 7 лет назад 0

Похожие вопросы