Решение, подходящее как для Linux, так и для Windows, состоит в том, чтобы просто привыкнуть к использованию консольного ffmpeg в вашем коде. Я складываю потоки, пишу простой класс контроллера потока, после чего вы можете легко использовать любую функциональность ffmpeg, которую хотите использовать.
В качестве примера, это содержит разделы, использующие ffmpeg для создания миниатюры из указанного мной времени.
В контроллере потока у вас есть что-то вроде
List<ThrdFfmpeg> threads = new List<ThrdFfmpeg>();
Это список потоков, которые вы запускаете, я использую таймер для поля этих потоков, вы также можете настроить событие, если полирование не подходит для вашего приложения. В этом случае класс Thrdffmpeg содержит,
public class ThrdFfmpeg
{
public FfmpegStuff ffm { get; set; }
public Thread thrd { get; set; }
}
FFmpegStuff содержит различные функции ffmpeg, thrd, очевидно, является потоком.
Свойство в FfmpegStuff — это класс FilesToProcess, который используется для передачи информации вызываемому процессу и получения информации после остановки потока.
public class FileToProcess
{
public int videoID { get; set; }
public string fname { get; set; }
public int durationSeconds { get; set; }
public List<string> imgFiles { get; set; }
}
VideoID (я использую базу данных) сообщает потоковому процессу, какое видео использовать, взятое из базы данных. fname используется в других частях моих функций, использующих FilesToProcess, но не используется здесь. durationSeconds — заполняется потоками, которые просто собирают продолжительность видео. imgFiles используется для возврата любых созданных эскизов.
Я не хочу увязнуть в своем коде, когда его целью является поощрение использования ffmpeg в легко контролируемых потоках.
Теперь у нас есть части, которые мы можем добавить в список потоков, поэтому в нашем контроллере мы делаем что-то вроде:
AddThread()
{
ThrdFfmpeg thrd;
FileToProcess ftp;
foreach(FileToProcess ff in `dbhelper.GetFileNames(txtCategory.Text))`
{
//make a thread for each
ftp = new FileToProcess();
ftp = ff;
ftp.imgFiles = new List<string>();
thrd = new ThrdFfmpeg();
thrd.ffm = new FfmpegStuff();
thrd.ffm.filetoprocess = ftp;
thrd.thrd = new `System.Threading.Thread(thrd.ffm.CollectVideoLength);`
threads.Add(thrd);
}
if(timerNotStarted)
StartThreadTimer();
}
Теперь полеринг наших тем становится простой задачей,
private void timerThreads_Tick(object sender, EventArgs e)
{
int runningCount = 0;
int finishedThreads = 0;
foreach(ThrdFfmpeg thrd in threads)
{
switch (thrd.thrd.ThreadState)
{
case System.Threading.ThreadState.Running:
++runningCount;
//Note that you can still view data progress here,
//but remember that you must use your safety checks
//here more than anywhere else in your code, make sure the data
//is readable and of the right sort, before you read it.
break;
case System.Threading.ThreadState.StopRequested:
break;
case System.Threading.ThreadState.SuspendRequested:
break;
case System.Threading.ThreadState.Background:
break;
case System.Threading.ThreadState.Unstarted:
//Any threads that have been added but not yet started, start now
thrd.thrd.Start();
++runningCount;
break;
case System.Threading.ThreadState.Stopped:
++finishedThreads;
//You can now safely read the results, in this case the
//data contained in FilesToProcess
//Such as
ThumbnailsReadyEvent( thrd.ffm );
break;
case System.Threading.ThreadState.WaitSleepJoin:
break;
case System.Threading.ThreadState.Suspended:
break;
case System.Threading.ThreadState.AbortRequested:
break;
case System.Threading.ThreadState.Aborted:
break;
default:
break;
}
}
if(flash)
{//just a simple indicator so that I can see
//that at least one thread is still running
lbThreadStatus.BackColor = Color.White;
flash = false;
}
else
{
lbThreadStatus.BackColor = this.BackColor;
flash = true;
}
if(finishedThreads >= threads.Count())
{
StopThreadTimer();
ShowSample();
MakeJoinedThumb();
}
}
Помещение ваших собственных событий в класс контроллера работает хорошо, но в работе с видео, когда мой собственный код фактически не выполняет какую-либо обработку видеофайла, поляризация с последующим вызовом события в управляющем классе работает так же хорошо.
Используя этот метод, я постепенно создал почти все функции видео и фото, которые, я думаю, когда-либо буду использовать, все они содержатся в одном классе, и этот класс в виде текстового файла можно использовать в версиях для Lunux и Windows с небольшим числом. предварительных директив.
person
Bob
schedule
15.07.2016