FFmpeg: Verkettung ohne Neucodierung

1183

Ich habe zwei * .mpg-Dateien. Ich möchte sie verketten, indem ich den Videostrom (MPEG-2) und den MP2-Audiostrom auswähle. Mein Problem ist, dass die Streams immer neu codiert werden. Ich möchte das gerne vermeiden, aber ich versage seit vielen Stunden, verschiedene Dinge zu versuchen.

Eingabedateien:

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: (einer der vielen versucht)

-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" 

Ausgabe:

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) 

Wie Sie sehen, ist die Ausgabe "mpeg1video", obwohl der Stream nur kopiert werden soll. Die Angabe von "-c copy" ist jedoch bei einem komplexen Filter nicht gültig. "-f mpeg" und "-f dvd" für die Ausgabedatei funktionieren ebenfalls nicht. Letzteres erstellt zwar einen MPEG-2-Videostream, verursacht aber auch eine erneute Codierung, obwohl dies nicht erforderlich ist.

Ich kenne das Eingabeformat "-f concat", aber was fehlt mir beim Versuch, diesen Weg zu gehen? Ich weiß, dass FFmpeg in der Lage ist, MPEG-2-Video und MP2-Audio in eine .mpg-Datei (PS-Format, nicht TS) zu muxen Streams wie beabsichtigt. Dies zeigt, dass bei einem MPEG-2-Videostream, einem MP2-Audiostream und der Erweiterung des Zieldateinamens ".mpg" automatisch der richtige Muxer ohne erneute Codierung verwendet wird. Im obigen Fall jedoch nicht.

Danke fürs Lesen.

0

1 Antwort auf die Frage

1
Gyan

Zwei Dinge: 1) Wenn Sie die Codec-Optionen nicht ausdrücklich auf festgelegt haben copy, wählt FFmpeg den Standardcodierer aus. Streams werden also nicht kopiert. 2) Der von Ihnen gezeigte Befehl ffmpeg verwendet den concat- Filter . Die Verwendung eines Filters für einen Stream macht es erforderlich, dass diese Streams erneut codiert werden. Dies liegt daran, dass Filter für decodierte Frames funktionieren, nicht für die in den Quellen vorhandenen codierten. Die Streams, die von keinem Filter verarbeitet werden, können weiterhin kopiert werden.

Hier müssen Sie den concat-Demuxer verwenden, von dem Sie wissen, dass Sie ihn kennen. Aber der Vollständigkeit halber ...

# 1 Erstellen Sie eine Textdatei mit der Aufschrift

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 
Danke Mulvya. Ich verstehe teilweise. Ich bin nicht sicher, warum Frames überhaupt decodiert werden. Der Concat-Filter benötigt keine decodierten Frames, da er die Streams nur verkettet. Folglich sollte nachträglich keine Kodierung erforderlich sein. Bedeutet das, dass FFmpeg jedes Mal, wenn ein komplexer Filter verwendet wird, die Frames decodiert, um sie an den / die Filter zu übergeben? (obwohl es nicht erforderlich ist) Thx für die Concat-Demuxer-Hinweise; So habe ich es gemacht. In der Zwischenzeit habe ich mkvmerge verwendet, um die Dateien zu speichern. Hat funktioniert. Obwohl ich immer noch daran interessiert bin, es für die Zukunft zu lernen. vor 7 Jahren 0
Die meisten Filter arbeiten für Bild-Raster oder Audio-Samples. Obwohl der Concat-Filter selbst dies nicht benötigt, müssen die Frames dennoch decodiert werden, da Filter vor oder nach der Kette möglicherweise erforderlich sind. Im ersten Fall werden decodierte Frames benötigt, und im letzteren Fall muss ein Decoder zwischen Filtern aufgerufen werden. Wenn ich es verstehe, lohnt sich das vielleicht nicht, wenn es in der aktuellen Architektur überhaupt möglich ist. Nur Streams, die irgendwo in den Filterkomplex eingespeist werden, werden decodiert. Gyan vor 7 Jahren 0
Jetzt weiß ich, warum ich alles versucht haben könnte, um eine erneute Kodierung zu vermeiden. ;) Vielen Dank. vor 7 Jahren 0