Уже несколько дней пытаюсь решить проблему. Я новичок в многопоточности. Моя цель — запустить несколько задач кодирования видео одновременно с помощью ffmpeg.exe
и использовать всю мощь сервера.
У меня есть оболочка С#, которая запускает процесс 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
— это количество потоков, используемых для внутренней обработки потоков ffmpeg. Когда я отключаю его, он не работает.
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 (или какого-либо другого механизма), потому что я хочу предотвратить сбой приложения и хочу управлять успехами и неудачами.