Der Titel drückt es zwar etwas laienhaft aus, aber hier ist das Problem: Man macht mittels DVB-T oder DVB-S eine Aufnahme, die im TS-Format (MPEG-TS, der Transport Stream) abgespeichert ist und will ein xvid-AVI daraus basteln. Viele Wege führen nach Rom, aber die meisten Enden irgendwo im Nirvana. Was passiert nämlich häufig? Durch das "seltsame" Format der DVB-Streams (namentlich MPEG-TS) entstehen AVI-Dateien, bei denen die Audio- gegen die Videospur zeitverschoben, also asynchron, sind (AV-Async werde ich das in Zukunft nennen). Ausgesprochen nervig, so etwas.
Und diese Probleme gibt es erst, wenn man überhaupt so weit kommt, dass man sich eine AVI-Datei erzeugen kann. Denn das Linux-Programm transcode kann das MPEG-TS-Format bedauerlicherweise nicht lesen.
Ausgangssituation
Die Ausgangssituation sieht wie folgt aus: Wir haben eine (große) Datei, ich nenne sie jetzt einfach einmal "AustinPowers.ts". Wir wollen am Ende eine "AustinPowers.avi" haben. Die ts-Datei hat folgende Eigenschaften:
- MPEG-TS Format
- Breite/Höhe: 720 x 576 Pixel
Verdeutlichung des Problems
Dass die MPEG-TS-Daten von der Speicherung her verschieden zu einer AVI-Datei sind, wird deutlich, wenn man sich einmal eine AVI-Datei mit dem MPlayer betrachtet, und auf die letzte Zeile achtet:
A: 2.2 V: 2.2 A-V: 0.003 ct: 0.000 55/ 55 8% 0% 0.6% 0 0 A: 268.0 V: 268.0 A-V: 0.002 ct: 0.264 6701/6701 5% 0% 0.5% 0 0
Egal an welcher Position des Streams man sich befindet, der Wert "A-V" (also die momentan Zeitdifferenz zwischen der Video- und Audiospur) bleibt stetig unter 5ms. Nun mit einem TS-Stream:
A:92227.6 V:92228.1 A-V: -0.475 ct: -0.024 11/ 11 ??% ??% ??,?% 0 0 A:92228.3 V:92228.7 A-V: -0.410 ct: -0.084 26/ 26 13% 1% 0.4% 3 0 A:92229.0 V:92229.3 A-V: -0.350 ct: -0.144 41/ 41 14% 0% 0.4% 6 0 A:92229.7 V:92229.9 A-V: -0.291 ct: -0.208 57/ 57 12% 1% 0.4% 9 0 A:92231.5 V:92231.6 A-V: -0.122 ct: -0.376 99/ 99 9% 1% 0.4% 12 0 A:92233.3 V:92233.3 A-V: -0.001 ct: -0.491 140/140 8% 0% 0.4% 15 0 A:92236.5 V:92236.5 A-V: -0.003 ct: -0.498 221/221 8% 0% 0.4% 18 0 A:92246.3 V:92246.3 A-V: 0.009 ct: -0.495 465/465 6% 0% 0.4% 22 0 A:92251.3 V:92251.3 A-V: 0.004 ct: -0.498 591/591 6% 0% 0.4% 26 0
Zunächst fällt auf, dass die Zeiten für Audio und Video kompletter Unsinn sind. Das ist normal, es ist ja auch ein Stream - dieser hat keinen "Anfang" und kein "Ende" in dem Sinn. Und man sieht deutlich, dass der MPlayer (der wirklich ausgesprochen geschickt mit dem Stream umgeht) zunächst einmal 6 Sekunden braucht, um überhaupt Video und Audio synchron zu bringen. In dem Stream sind nämlich Informationen kodiert, die diesen Versatz angeben. Deshalb ist auch zum Beispiel beim direkten Abspielen von DVB-T mit dem MPlayer in den ersten Paar Sekunden die Audiospur nicht synchron mit der Videospur. Dasselbe Phänomen kann man mit vielen VDRs (Video Disk Recordern) beobachten.
Wie es nicht funktioniert
Da ich mich einen ganzen Tag damit herumgeschlagen habe, das hier zum Laufen zu bringen, weiß ich mittlerweile viele Möglichkeiten, bei denen es schief gehen kann. Diese will ich hier aufführen, damit sich andere Leute die Zeit sparen können. Nicht zu Nachahmung empfohlen, alles führt zu defekten AVIs!
Erster Versuch: mencoder benutzen.
joe joe [~/austinpwrs]: mencoder -oac copy -ovc copy -o Temp1.avi AustinPowers.ts joe joe [~/austinpwrs]: mencoder -oac copy -ovc copy -forceidx -o Temp2.avi Temp1.avi joe joe [~/austinpwrs]: rm -f Temp1.avi joe joe [~/austinpwrs]: transcode -x mplayer,mplayer -y xvid -o AustinPowers.avi -i Temp2.avi joe joe [~/austinpwrs]: rm -f Temp2.avi
Das funktioniert zwar (also erzeugt ein AVI-File), allerdings mit einem Problem: Die Audiospur ist (möglicherweise) gegen die Videospur verschoben. Nicht immer, sondern abhängig davon, zu welchem Zeitpunkt der Stream aufgenommen wurde. Bei mir sind das konstant 400ms gewesen, schon viel zu hoch, um es nicht zu bemerken. Keine gute Idee also.
Zweiter Versuch: vlc benutzen, um aus dem TS (Transport Stream) eine PS-MPEG (Program Stream) zu erzeugen.
joe joe [~/austinpwrs]: vlc -I dummy AustinPowers.ts '--sout=#standard{access=file,mux=ps,dst=Temp.ps}' vlc:quit joe joe [~/austinpwrs]: transcode -x mplayer,mplayer -y xvid -o AustinPowers.avi -i Temp.ps joe joe [~/austinpwrs]: rm -f Temp.ps
Hat leider exakt dasselbe Problem wie mit dem mencoder.
Dritter Versuch: vlc benutzen, um aus dem TS (Transport Stream) direkt (also ohne transcode) eine xvid-AVI-Datei zu erzeugen.
joe joe [~/austinpwrs]: vlc -I dummy AustinPowers.ts '--sout=#transcode{vcodec=mp4v,acodec=mpga,vb=1600,ab=128}:standard{mux=avi,access=file,dst=AustinPowers.avi}' vlc:quit
Erzeugt zwar eine AVI-Datei, aber eine, bei der Video und Audio wieder asynchron sind...
Vierter Versuch: Bei meiner Recherche bin ich hier auf ein Programm Namens "replex" gestoßen, welches genau das leisten sollte, was ich mir wünschte: Eine TS-Videodatei neu Multiplexen (Audio/Video zerlegen und wieder zusammensetzen).
joe joe [~/austinpwrs]: replex -o Temp1.mpg -t MPEG2 AustinPowers.ts [...] video PTS inconsistent: 25:37:19.832 8:56:11.728 8:02:35.915 8:56:11.880 diff: 0:53:35.813 fixed video frame 80399 ringbuffer overflow 0<184 6291456 ring buffer overflow in get_pes 6291456 joe joe [~/austinpwrs]: replex -f -o Temp1.mpg -t MPEG2 AustinPowers.ts [...] error while peeking audio ring -1 (576) error while peeking audio ring -1 (576) error while peeking audio ring -1 (576) [...]
Allerdings war es in der Version 0.1.4 nicht benutzbar, sondern stürzte bei der Behandlung der Datei mit obiger Fehlermeldung ab. Version 0.1.6.8 stürzte mit derselben Fehlermeldung ab, tat jedoch etwas sinnvolles, wenn man es mit der zusätzlichen Option "-f" alle PTS-Informationen des Eingangsstreams ignorieren lies. Allerdings stürzte es dann in einer anderen Weise ab, es hängt einfach gegen Ende in einer Endlosschleife, die immer die Meldung "error while peeking audio ring -1 (576)" anzeigt. Keine Alternative also, schade. Das Programm sieht nämlich an und sich vielversprechend aus...
Fünfter Versuch: Benutzung von ffmpeg um ein Demultiplexing/Remultiplexing zu ermöglichen.
joe joe [~/austinpwrs]: ffmpeg -i AustinPowers.ts -vcodec mpeg2video -acodec copy AustinPowers.mpg
Das erzeugt zwar eine Datei "AustinPowers.mpg", die allerdings schrecklich aussieht (sehr verpixelt) und zudem noch schrecklich A/V-asynchron ist.
So geht es!
Nach all der Frustration habe ich ein Tool gefunden, das "projectx" heißt und damit die Lösung der oben beschriebenen Probleme bedeutete. Man kann es hier finden. Insgesamt werden also folgende Tools benötigt:
- projectx (Gentoo-Paket media-video/projectx)
- dvb-mplex (Gentoo-Paket media-libs/libdvb)
- transcode (Gentoo-Paket media-video/transcode)
Alles (bis auf projectx) sollte auf einem System, das DVB-x abspielen kann, schon installiert sein. Zunächst einmal muss man die TS-Datei demultiplexen, also in ihre Audio- und Videokomponente zerlegen:
joe joe [~/austinpwrs]: projectx -name Demux AustinPowers.ts
Wir erhalten nach Bearbeitung zwei Dateien, Demux.m2v (das Video) und Demux.mp2 (die Audiospur). Diese wollen wir jetzt wieder remultiplexen:
joe joe [~/austinpwrs]: dvb-mplex -o AustinPowers.mpg -t MPEG1 -i ES_STREAM Demux.mp2 Demux.m2v joe joe [~/austinpwrs]: rm -f Demux.m2v Demux.mp2
Hierbei ist wichtig, dass die Audio- und Videodaten dem Programm "dvb-mplex" in exakt dieser Reihenfolge übergeben werden, sonst funktioniert es nicht. Als Resultat haben wir nun ein Video, in dem Audio- und Video synchron gemultiplext (interleaved, also verschränkt) ist. Dieses soll im Letzten Schritt nun zu xvid transkodiert werden:
joe joe [~/austinpwrs]: transcode -i AustinPowers.mpg -o AustinPowers.avi -y xvid4 joe joe [~/austinpwrs]: rm -f AustinPowers.mpg
Das funktioniert schon mal! Natürlich kann man den Aufruf verfeinern. Beispielsweise wollen wir angeben mit welcher Bitrate der Videostream kodiert werden soll (1600 kbps), oder dass oben und unten jeweils 72 Pixel und rechts und links jeweils 16 Pixel weggeschnitten werden (damit die schwarzen Balken nicht mit in der AVI-Datei sind, verschwendet ja nur Platz). Der Aufruf lautet dann:
joe joe [~/austinpwrs]: transcode -i AustinPowers.mpg -o AustinPowers.avi -y xvid4 --pre_clip 72,16,72,16 -w 1600
Außerdem kann man noch, wenn einen die Interlacing-Linien stören (z.B. bei links/rechts-Schwenks deutlich erkennbar), transcode noch mitteilen, einen Deinterlacer zu benutzen. transcode bietet viele davon an, bei mir hat allerdings nur ein einziger richtig (und auch gut) funktioniert:
joe joe [~/austinpwrs]: transcode -i AustinPowers.mpg -o AustinPowers.avi -y xvid4 --pre_clip 72,16,72,16 -w 1600 -J smartyuv
Die zwei Interlacer "smartbob" und "smartdeinter" haben bei mir nur völlig verzerrte, verschleierte Zielvideos produziert, ich habe keine Ahnung weiß, weshalb.
Werbung rausschneiden
Zu guterletzt kann man das Video noch nachbearbeiten, indem man die Werbung herausschneidet. Dazu eignet sich das Programm "avidemux" hervorragend (Gentoo-Paket media-video/avidemux). Man startet avidemux einfach und lädt die AVI-Datei. Dann geht man an den Anfang eines Werbeblocks und setzt die Startmarkierung durch Drücken der "[" Taste. Zum Ende des Werbeblocks gehen und die "]" Taste drücken. Dann einfach die "Entf"-Taste drücken und der Block ist verschwunden. Das macht man mit allen Werbeblöcken. Sobald man fertig ist, einfach auf "Speichern" klicken, das Video unter einem neuen Namen speichern (z.B. AustinPowersOhneWerbung.avi) und - tadaa!
Viel Erfolg!
Ich hoffe, die Anleitung ist gut genug, freue mich natürlich immer über Kommentare. Besonders wenn Programme, bei denen ich beschreibe, dass sie nicht funktionieren, in einer neuen Version doch gehen, bin ich über einen Hinweis dankbar - ich kann das hier eben auch nicht ständig aktualisieren.

