Ich versuche schon seit einigen Tagen, ein Problem zu lösen. Ich bin ein Anfänger im Bereich Multithreading. Mein Ziel ist es, mehrere Videokodierungsaufgaben gleichzeitig auszuführen, indem ich ffmpeg.exe
und die gesamte Leistung des Servers zu nutzen.
Ich habe einen C#-Wrapper, der die ffmpeg.exe
Prozess und funktioniert ohne Threading (oder nur mit ffmpeg-internem Threading (nicht verfügbar für die flv-Kodierung)), was wie folgt aussieht:
using (Process process = new Process())
{
process.StartInfo.FileName = encoderPath + "ffmpeg.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = false;
string arguments = "-y -i " + filenameInput + " -f " +
GetVideoFormatName(format) + " -vcodec " + GetVideoCodecName(codec);
// (most argument setup has been omitted for brevity)
arguments += " " + filenameOutput + " ";
process.StartInfo.Arguments = arguments;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
bool succes = LireSortie(process);
process.WaitForExit();
process.Close();
return succes;
}
Der folgende Code ruft den Wrapper auf. Der zweite Parameter eines jeden Encode
Methode ist die Anzahl der Threads, die für das interne ffmpeg-Threading verwendet werden sollen. Wenn ich es deaktiviere, funktioniert es nicht.
var fm = new FFMpegWrapper();
fm.FilenameInput = "test.mp4";
//VideoInfo videoinfo = fm.GetVideoInfo();
Task[] tasks = {
Task.Factory.StartNew(
new Action(()=>{ fm.Encodeto200p("test200p.mp4", 4); })),
Task.Factory.StartNew(
new Action(()=>{ fm.EncodetoFlash200p("test200p.flv"); })),
// ... (calls to other Encode methods ommitted) ...
Task.Factory.StartNew(
new Action(()=>{ fm.Encodeto404p("test404p.mp4", 4); })),
Task.Factory.StartNew(
new Action(()=>{ fm.EncodetoFlash404p("test404p.flv"); })),
Task.Factory.StartNew(
new Action(()=>{ fm.Encodeto720p("test720p.mp4", 4); }))
};
Task.WaitAll(tasks, 5000);
Sie fragen sich wahrscheinlich, warum ich ein Timeout von 5000 für WaitAll()
. Das liegt daran, dass der aufrufende Thread auf unbestimmte Zeit wartet, weil TPL kein Ende der Aufgaben erkennt. ffmpeg.exe
Prozesse "stoppen" in der Mitte der Kodierung und laufen mit 0% der CPU weiter.
Ich denke, TPL und Process
sind widersprüchlich. Wenn ich den Status der einzelnen Aufgaben mit TPL abrufe, bleibt er die ganze Zeit über "Running". Ich möchte die tatsächlichen Ereignisse von ffmpeg-Prozessen mit TPL (oder einem anderen Mechanismus) erfassen, weil ich verhindern möchte, dass die Anwendung abstürzt, und Erfolge und Misserfolge verwalten möchte.