Ich habe einen Stream von einer Instanz von FFmpeg zu einer anderen geleitet, aber da die Komprimierung für den Zwischen-Stream verwendet wurde, war das Endergebnis hässlich. Ich brauche eine verlustfreie Pipe, um dies zu verhindern, und ich möchte, dass sie sowohl Audio als auch Video enthält.
Ich vermute, dass es mehr als eine Antwort auf dieses Problem gibt, daher gehen Bonuspunkte an jeden, der eine umfassende Liste von Lösungen bereitstellt (kompatible Container und Codecs, die weitergeleitet werden können). Bonuspunkte gehen auch an alle, die andere Daten wie Untertitel berücksichtigen.
EDIT: Ich suche nach geeigneten Codec / Container-Kombinationen. Ich weiß nicht, warum die Leute Schwierigkeiten hatten, das herauszufinden, da ich sagte, ich habe bereits eine Pfeife benutzt und jetzt muss sie verlustfrei sein.
Ich weiß nicht, wie ich das erklären soll, ohne eingebildet zu klingen, aber dies ist eine FAQ-Seite. Das Stellen von Fragen, die äußerst spezifische Antworten erfordern, hilft den Millionen von Benutzern, die diese Website erreichen, nicht, indem sie ihre eigenen Probleme in Suchmaschinen eingeben. Meine Frage sollte allen anderen helfen, die verlustfrei Daten zwischen FFmpeg-Instanzen weiterleiten müssen, ohne alle mit einer Wand aus Erzählungen und Code abzulenken, in der erklärt wird, was ich getan habe, warum es nicht funktioniert hat und warum dies die einzige Option ist.
Antworten:
Wie man verlustfrei Video und Audio von leitet
ffmpeg
nachffmpeg
Anforderungen des Fragestellers:
ffmpeg
zur nächsten leiten/dev/null
Beispiel:
Ich sehe keinen Grund, warum jemand dies tun würde. Es gibt auch nur sehr wenige Gründe, von
ffmpeg
zu zu leiten ,ffmpeg
wenn Sie höchstwahrscheinlich nur einen verwenden könnenffmpeg
Prozess verwenden können, um das zu tun, was Sie wollen.Was die Optionen tun:
-s 1280x720 -f rawvideo
- Optionen zur Beschreibung der Eingabe, da dies/dev/zero
kein typisches Eingabeformat ist und daher diese zusätzlichen Optionen erforderlich sind.-i /dev/zero
- Der Videoeingang. In diesem Beispiel wird es verwendet, um einen Videostream aus "nichts" zu generieren. Dies wurde im Beispiel verwendet, weil der Fragesteller sich weigerte, Informationen über die verwendeten Eingaben bereitzustellen.-ar 48000 -ac 2 -f s16le
- Optionen zur Beschreibung der Eingabe, da dies/dev/zero
kein typisches Audioformat ist.-i /dev/zero
- Der Audioeingang. In diesem Beispiel wird es verwendet, um einen Audiostream aus "nichts" zu generieren.-c copy
- Kopieren Sie die Eingänge zum Ausgang oder kopieren Sie sie erneut. Es wird keine Neucodierung durchgeführt, sodass der Prozess verlustfrei ist. Es ist nicht bekannt, ob das Kopieren von Streams für den Fragesteller akzeptabel ist oder nicht. Vielleicht ist stattdessen eine Neucodierung erwünscht?-f nut
- Sie müssen angeben,ffmpeg
welches Format für die Pipe verwendet werden soll. Nuss ist ein Behälterformat. Sieheffmpeg -formats
für eine vollständige Liste. Ein anderes flexibles Format ist-f matroska
, aber es ist unmöglich, ein geeignetes oder spezifisches Ausgabecontainerformat vorzuschlagen, das ohne weitere Informationen des Fragestellers verwendet werden soll.pipe:1
- Verwenden Sie daspipe
Protokoll, um auf stdout auszugeben. Alternativ kann die Nummer (nurpipe:
) weggelassen werden und standardmäßig wird der stdout-Dateideskriptor zum Schreiben und stdin zum Lesen verwendet.quelle
ssh [email protected] "ffmpeg -i $URL -c copy -f nut pipe:1" | ffplay -i pipe:0
/dev/null
als endgültige Ausgabe zu verwenden.Die Art und Weise, wie ich dies gelernt habe (aus Teilen früherer Antworten), besteht darin, den
rawvideo
Codec für das Video, denpcm_s16le
Audio-Codec und den FFmpeg-nut
Wrapper zum Codieren des Streams zu verwenden.nut
wird von großen Programmen außerhalb von FFmpeg nicht unterstützt, aber es ist der einzige mir derzeit bekannte Container, der die unkomprimierten Formate unterstützt, die zum effizienten Weiterleiten von Daten zwischen Prozessen erforderlich sind.Die Argumente für diese Codierung könnten folgendermaßen aussehen:
Einige Audiodaten werden mit 24-Bit- oder größeren Samples gespeichert. Für diese sollten Sie stattdessen
pcm_24le
ein anderes Format verwenden. Die vollständige Liste der unkomprimierten Audioformate wird durch Ausführen aufgelistetffmpeg -codecs
(Sie müssen die Liste nach ihnen durchsuchen). Wenn Sie die Sample-Größe Ihres Audios nicht kennen,pcm_16le
sollte die Verwendung keinen merklichen Qualitätsverlust verursachen.Setzen Sie am empfangenden Ende der Pipe die Eingabe auf Standardeingabe, und ffmpeg erkennt das Format und dekodiert den Stream.
Die Ellipsen (...) in dieser Antwort sind nicht Teil des Codes. Hier geht Ihr Code hin. Die einzelnen Bindestriche (-) weisen FFmpeg an, entweder Standardeingabe oder Standardausgabe zu verwenden, je nachdem, wo sie angezeigt werden.
AKTUALISIEREN:
Ich habe ein einfaches Experiment versucht, um dies zu verbessern, und es scheint, dass AVI ein besserer Container ist, da andere Programme dies verstehen werden (zumindest VLC).
Dies funktioniert genau wie die alte Version, mit dem zusätzlichen Bonus der Kompatibilität.
Im Nachhinein habe ich es bereut, eine Frage gestellt zu haben, die in vielen Situationen nicht hilfreich war, obwohl ich behauptete, dass Fragen für alle hilfreich sein sollten. Dies macht die Antwort nützlicher.
quelle
-c:v yuv4
ist ein Codec, deryuv420p
Rohvideos mit pix_fmt liest / schreibt . Wenn Sie bei rawvideo einen Filter hinzufügen / entfernen, wird die Ausgabe möglicherweise in einem anderen Pixelformat belassen, wenn der Filter das Pixelformat des Videos nicht unterstützt.Das eine Problem mit der anderen Antwort ist, dass es pcm_s16le ist, nicht s16le. Außerdem enthält es viele redundante Parameter.
Ich würde pcm anstelle von flac in der Pipe verwenden, da die Verarbeitung viel weniger Zeit in Anspruch nimmt (PCM ist Roh-Audio, FLAC benötigt viel Zeit zum Codieren).
Wie auch immer, hier ist, wie ich es machen würde.
ffmpeg -i <input video file/stream> -vcodec rawvideo -acodec pcm_s16le pipe:1 | ffmpeg -f rawvideo -i - -vcodec <video output codec> -acodec <audio output codec> -vb <video bitrate if applicable> -ab <audio bitrate if applicable> <final-output-filename>
Dies funktionierte für mich, als ich es das letzte Mal versuchte, aber mein Ziel war es, ffmpeg in ffplay zu leiten, was ein etwas anderer Prozess ist.
Beispiel:
Dadurch wird ein Video von ffmpeg als Rohvideoausgabe und 16-Bit-Little-Endian-PCM an eine andere Instanz weitergeleitet (beide verlustfrei, es sei denn, Sie haben 24-Bit-PCM, dann ersetzen
pcm_s24le
). Anschließend werden sie in der zweiten Instanz mit dem Fraunhoefer in h.264 konvertiert AAC-Bibliothek aus dem Android-Projekt (libfaac
ist häufiger in ffmpeg-Builds enthalten. Sie können sie stattdessen durch diese ersetzen.)ffmpeg -i montypythonsflyingcircus-s1e1.avi -vcodec rawvideo -acodec pcm_s16le pipe:1 | ffmpeg -i - -vcodec libx264 -acodec libfdk_aac -vb 1200k -ab 96k mpfc-s1e01-output.mkv
Wenn dies die Untertitel nicht weiterleitet, können Sie sie jederzeit in SRTs rippen und später wieder einfügen oder sie einfach zu den obigen Pipes hinzufügen.
quelle
s16le
meinem Beispiel ist nichts auszusetzen . Sie verwechseln dass16le
Format mit dempcm_s16le
Codec. Sieheffmpeg -formats
undffmpeg -codecs
(oderffmpeg -encoders
oderffmpeg -encoders
) für alle verfügbaren Formate und Codecs. ffmpeg muss mitgeteilt werden, für welches Format es verwendet werden soll/dev/zero
. Welche Parameter halten Sie für redundant?-f
Option) definieren, das ffmpeg für die Pipe-Ausgabe verwenden soll.Unable to find a suitable output format for 'pipe:1'
. Haben Sie versucht, den Befehl auszuführen? @Wutaz, hat das wirklich für dich funktioniert? Ich wäre sehr überrascht, wenn es so wäre.