Wie kann ich Daten verlustfrei zu und von FFmpeg weiterleiten?

7

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.

Wutaz
quelle
3
Was hast du versucht? Bitte zeigen Sie Ihren Befehl ffmpeg und die vollständige Ausgabe der ffmpeg-Konsole. Warum leiten Sie von ffmpeg zu ffmpeg? Bitte geben Sie weitere Details darüber an, was Sie tun und was Sie erreichen möchten.
Llogan
Wenn die Pipe verlustfrei ist und Audio und Video enthält, spielt es keine Rolle, ob sie zu / von / dev / null geht. Der Kontext würde dies nur erschweren.
Wutaz
1
Ich stimme dir nicht zu. Wenn ich zumindest Ihre ffmpeg-Version und deren Konfiguration sowie Informationen zu Ihren Eingaben (die Konsolenausgabe reicht aus) und Ihren Ausgabeanforderungen kenne, kann ich eine genauere Antwort geben.
Llogan
Die FFmpeg-Konfiguration kann ich verstehen, aber selbst wenn sich FFmpeg ändert, bezweifle ich, dass die Unterstützung für unkomprimierte Streams jemals ein Problem sein wird. Wenn Sie etwas wissen, das das zu verwendende ideale Format ändern kann, listen Sie bitte alle auf und wann jedes geeignet ist. Wenn Sie nur eine enge Antwort geben, wird die Frage nicht richtig beantwortet.
Wutaz

Antworten:

11

Wie man verlustfrei Video und Audio von leitet ffmpeg nachffmpeg

Anforderungen des Fragestellers:

  • verlustfrei Pipe aus einer Instanz von ffmpeg zur nächsten leiten
  • Es ist egal, ob es hin und her geht /dev/null

Beispiel:

ffmpeg -s 1280x720 -f rawvideo -i /dev/zero -ar 48000 -ac 2 -f s16le -i \
/dev/zero -c copy -f nut pipe:1 | ffmpeg -y -i pipe:0 -c copy -f nut /dev/null

Ich sehe keinen Grund, warum jemand dies tun würde. Es gibt auch nur sehr wenige Gründe, von ffmpegzu zu leiten , ffmpegwenn 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/zerokein 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/zerokein 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, ffmpegwelches Format für die Pipe verwendet werden soll. Nuss ist ein Behälterformat. Siehe ffmpeg -formatsfü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 das pipeProtokoll, um auf stdout auszugeben. Alternativ kann die Nummer (nur pipe:) weggelassen werden und standardmäßig wird der stdout-Dateideskriptor zum Schreiben und stdin zum Lesen verwendet.

llogan
quelle
4
Es auf jeden Fall sind Gründe , warum Sie wollen würde , dies zu tun. Ein Anwendungsfall ist das Weiterleiten eines Videostreams über einen SSH-Tunnel zur sicheren Fernanzeige:ssh [email protected] "ffmpeg -i $URL -c copy -f nut pipe:1" | ffplay -i pipe:0
Yuval A
1
@ YuvalA Ich bezog mich auf die feste Anforderung des OP, /dev/nullals endgültige Ausgabe zu verwenden.
Llogan
7

Die Art und Weise, wie ich dies gelernt habe (aus Teilen früherer Antworten), besteht darin, den rawvideoCodec für das Video, den pcm_s16leAudio-Codec und den FFmpeg- nutWrapper zum Codieren des Streams zu verwenden.nutwird 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:

... -c:v rawvideo -c:a pcm_16le -f nut - ...

Einige Audiodaten werden mit 24-Bit- oder größeren Samples gespeichert. Für diese sollten Sie stattdessen pcm_24leein anderes Format verwenden. Die vollständige Liste der unkomprimierten Audioformate wird durch Ausführen aufgelistet ffmpeg -codecs(Sie müssen die Liste nach ihnen durchsuchen). Wenn Sie die Sample-Größe Ihres Audios nicht kennen, pcm_16lesollte 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.

... ffmpeg -i - ...

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).

... -c:v rawvideo -c:a pcm_16le -f avi - ...

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.

Wutaz
quelle
2
hast du mkv ausprobiert? Ich unterstütze Untertitel und ich denke, jeder Codec, den ffmpeg unterstützt, kann in mkv gemuxt werden. Im Gegensatz zu mp4 wird mkv abgespielt, ohne dass das Ende der Datei angezeigt werden muss, sodass es möglicherweise in einer Pipe funktioniert.
Peter Cordes
Außerdem gibt es benannte Codecs für verschiedene Rohvideoformate, sodass Sie nicht das Risiko eingehen, dass Ihre Pixelformate bei der Ausgabe / Eingabe nicht übereinstimmen. zB -c:v yuv4ist ein Codec, der yuv420pRohvideos 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.
Peter Cordes
0

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 ( libfaacist 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.

Wyatt8740
quelle
Vielen Dank. Ich hatte gehofft, eine Alternative zu FLAC zu finden, weil ich weiß, dass es mehr Zeit erfordert.
Wutaz
1
An s16lemeinem Beispiel ist nichts auszusetzen . Sie verwechseln das s16leFormat mit dem pcm_s16leCodec. Siehe ffmpeg -formatsund ffmpeg -codecs(oder ffmpeg -encodersoder ffmpeg -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?
Llogan
1
Außerdem müssen Sie explizit das Format (mit -fOption) definieren, das ffmpeg für die Pipe-Ausgabe verwenden soll.
Llogan
Das funktioniert nicht. Wenn Sie kein Ausgabeformat angeben, erhalten Sie nur 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.
Slhck
1
@Wutaz Lassen Sie mich hier nur meine zwei Cent hinzufügen, basierend auf meiner Erfahrung als Mitglied seit über drei Jahren und als Community-Moderator: Stack Exchange-Websites sind keine FAQ-Websites. Es handelt sich um Q & A-Sites zu spezifischen und tatsächlichen Problemen, mit denen Sie konfrontiert sind. Die Leute sollten nach ihrem eigentlichen Problem fragen und nicht nach ihrer Meinung nach die Lösung. Andernfalls führt dies nur zu Verwirrung und im Allgemeinen zu Fragen und Antworten, die für niemanden wirklich nützlich sind. Ich weiß ehrlich gesagt nicht, was ich mit dieser Frage anfangen soll.
Slhck