Ich verstehe den Befehl nicht vollständig, aber Ihre Beschreibung sieht so aus, als ob es sich um einen Auftrag für Named Pipes handelt. Um dieses Konzept zu verdeutlichen, verwendet mein Beispiel vier davon. Mit geeigneten Substitutionen kann man diese Zahl auf zwei reduzieren, denke ich, vielleicht sogar auf eins; aber jetzt halten wir es einfach.
mkfifo pre-audio-pipe pre-video-pipe audio-pipe video-pipe # creating pipes (reading commands) | mbuffer -p 1 -m 5G | tee pre-audio-pipe > pre-video-pipe # splitting
Dieser Prozess füllt die Puffer, die für die beiden genannten Pipes erstellt werden, und wartet, bis diese Daten an anderer Stelle gelesen werden.
Das "Anderswo" befindet sich in einer anderen Konsole:
<pre-audio-pipe (isolate audio) | (process audio) > audio-pipe
und in noch einer anderen Konsole:
<pre-video-pipe (isolate video) | (process video) > video-pipe
Wieder warten diese beiden Befehle, bis wir einige Daten aus den Pipes lesen. In der letzten Konsole:
ffmpeg -i video-pipe -i audio-pipe (doing final conversion)
Es kann zu einer Sperrung kommen, falls der letzte Befehl einen Stream vor dem anderen lesen möchte. Ich weiß nicht, wie wahrscheinlich das ist. Zusätzliche Puffer können hilfreich sein, um dies zu vermeiden. Mein erster Versuch wäre, die mbuffer
(zuvor tee
) zu entfernen und zwei unabhängige Puffer zwischen den jeweiligen (isolate)
und einzufügen (process)
.
Nachdem alles fertig ist:
rm pre-audio-pipe pre-video-pipe audio-pipe video-pipe # cleaning
Bearbeiten
Aus dem Kommentar der OP:
sehen Sie eine Chance, eine Lösung ohne separate Named Pipes zu implementieren?
Ich habe über Koprozessecoproc
nachgedacht ( eingebaut), aber ich kenne sie nicht viel. Es gibt diese umfassende Antwort darauf . Suchen Sie nach dem Satz "Warum sie nicht so beliebt sind". Von dort:
Der einzige Vorteil der Verwendung
coproc
ist, dass Sie die benannten Pipes nach der Verwendung nicht bereinigen müssen.
Ich bin völlig einverstanden. Sehen Sie sich das Beispiel dort an. Dies ist im Grunde Ihr Fall, wenn der Datenstrom drei- statt zweiwege-gegabelt ist. Das Beispiel verwendet andere Schalen als, bash
aber aus meiner Erfahrung wäre es in ähnlicher Weise schrecklich bash
.
Im Idealfall würde es einen einzeiligen Befehl geben, der nur mit unbenannten Pipes arbeitet, da der Job mit einem "wirtschaftlichen Aufwand" von der Eingabeaufforderung aus gestartet werden sollte.
Ernst? Mit all denen (doing some encoding here)
erweitert? Meiner Meinung nach, egal ob Sie benannte oder unbenannte Pipes verwenden, wird es "wirtschaftlich" sein, ein Skript zu schreiben, auch wenn es sich um einen einmaligen Job handelt. Ich vergleiche lange Einzeiler und gleichwertige gut geschriebene Skripte und finde das Debuggen einfacher.
Aber da Sie nach einem Einzeiler gefragt haben, erhalten Sie ihn immer noch mit Named Pipes. Meine Idee zur Verwaltung von Named Pipes ist das Erstellen eines temporären Verzeichnisses für sie. Das allgemeine Konzept:
my_temp=`mktemp -d` ; pre_audio_pipe="$/pre-audio-pipe" ; pre_video_pipe="$/pre-video-pipe" ; audio_pipe="$/audio-pipe" ; video_pipe="$/video-pipe" ; mkfifo "$pre_audio_pipe" "$pre_video_pipe" "$audio_pipe" "$video_pipe" ; (reading commands) | tee "$pre_audio_pipe" > "$pre_video_pipe" & <"$pre_audio_pipe" (isolate audio) | mbuffer -p 1 -m 1G | (process audio) > "$audio_pipe" & <"$pre_video_pipe" (isolate video) | mbuffer -p 1 -m 4G | (process video) > "$video_pipe" & ffmpeg -i "$video_pipe" -i "$audio_pipe" (doing final conversion) ; rm -rf "$my_temp"
Laut dieser Antwort können Sie sie wahrscheinlich in eine Befehlszeile einfügen, auch nachdem Sie den Befehl eingraviert und alle (do something)
Platzhalter erweitert haben.
OK, das One-Liner-Formular sollte Ihnen zeigen, wie unpraktisch es sein kann. Das gleiche Konzept wie ein Skript:
#!/bin/bash my_temp=`mktemp -d` pre_audio_pipe="$/pre-audio-pipe" pre_video_pipe="$/pre-video-pipe" audio_pipe="$/audio-pipe" video_pipe="$/video-pipe" mkfifo "$pre_audio_pipe" "$pre_video_pipe" "$audio_pipe" "$video_pipe" #creating actual pipes # Main code here. # Notice we put few commands into the background. # In this example there are two separate mbuffers. (reading commands) | tee "$pre_audio_pipe" > "$pre_video_pipe" & # splitting <"$pre_audio_pipe" (isolate audio) | mbuffer -p 1 -m 1G | (process audio) > "$audio_pipe" & <"$pre_video_pipe" (isolate video) | mbuffer -p 1 -m 4G | (process video) > "$video_pipe" & ffmpeg -i "$video_pipe" -i "$audio_pipe" (doing final conversion) # Then cleaning: rm -rf "$my_temp"