Я пытался решить проблему в течение нескольких дней. Я новичок в многопоточности. Моя цель - запустить несколько задач кодирования видео одновременно с помощью ffmpeg.exe
и использовать все возможности сервера.
У меня есть оболочка C #, которая запускает процесс ffmpeg.exe
и работает без многопоточности (или только с внутренней потоковой обработкой ffmpeg (недоступно для кодирования flv)), которая выглядит следующим образом:
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;
}
Код ниже вызывает оболочку. Вторым параметром каждого метода Encode
является количество потоков, которое нужно использовать для внутренней многопоточности. Когда я отключаю его, он не работает.
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);
Вы, наверное, задаетесь вопросом, почему я поставил таймаут 5000 для WaitAll()
. Это потому, что вызывающий поток ждет неопределенно долго, потому что TPL не обнаруживает конец задач. ffmpeg.exe
обрабатывает «останов» в середине кодировки и продолжает работать с 0% ЦП.
Я думаю, что TPL и Process
противоречат друг другу. Когда я получаю статус каждой задачи с помощью TPL, она остается «Выполнена» все время. Я хотел бы фиксировать реальные события процессов ffmpeg с помощью TPL (или другого механизма), потому что я хочу предотвратить сбой приложения и хочу управлять успехами и сбоями.