Я знаю, что в C ++ очень заманчиво получить правильную разбивку видеофайлов и просто сделать это самостоятельно. Но, несмотря на то, что информация там есть, это такие затянутые классы построения процессов, которые позволяют обрабатывать каждый формат файла и легко изменять его, чтобы учитывать будущие изменения структуры, что, честно говоря, это просто не стоит усилий.
Вместо этого я рекомендую ffmpeg. Это упоминалось выше, но говорит, что это сложно, это не сложно. Есть гораздо больше вариантов, чем нужно большинству людей, что делает его более сложным, чем он есть. Для большинства операций вы можете просто позволить ffmpeg все сделать самостоятельно.
Например преобразование файла
ffmpeg -i inputFile.mp4 outputFile.avi
С самого начала определите, какие операции ffmpeg будут выполняться в потоке или, точнее, в библиотеке потоков. Но имейте свой собственный класс потока, оберните его так, чтобы вы могли иметь свои собственные EventAgs и методы проверки потока завершены. Что-то вроде: -
ThreadLibManager()
{
List<MyThreads> listOfActiveThreads;
public AddThread(MyThreads);
}
Your thread class is something like:-
class MyThread
{
public Thread threadForThisInstance { get; set; }
public MyFFMpegTools mpegTools { get; set; }
}
MyFFMpegTools performs many different video operations, so you want your own event
args to tell your parent code precisely what type of operation has just raised and
event.
enum MyFmpegArgs
{
public int thisThreadID { get; set; } //Set as a new MyThread is added to the List<>
public MyFfmpegType operationType {get; set;}
//output paths etc that the parent handler will need to find output files
}
enum MyFfmpegType
{
FF_CONVERTFILE = 0, FF_CREATETHUMBNAIL, FF_EXTRACTFRAMES ...
}
Вот небольшой фрагмент моего класса инструментов ffmpeg, в этой части собрана информация о видео.
Я помещаю FFmpeg в определенное место, и в начале работы программного обеспечения оно удостоверяется, что оно там есть. Для этой версии я переместил его на рабочий стол, я уверен, что правильно написал для вас путь (я действительно ненавижу систему специальных папок MS, поэтому я игнорирую ее настолько, насколько могу).
В любом случае, это пример использования ffmpeg без окон.
public string GetVideoInfo(FileInfo fi)
{
outputBuilder.Clear();
string strCommand = string.Concat(" -i \"", fi.FullName, "\"");
string ffPath =
System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";
string oStr = "";
try
{
Process build = new Process();
//build.StartInfo.WorkingDirectory = @"dir";
build.StartInfo.Arguments = strCommand;
build.StartInfo.FileName = ffPath;
build.StartInfo.UseShellExecute = false;
build.StartInfo.RedirectStandardOutput = true;
build.StartInfo.RedirectStandardError = true;
build.StartInfo.CreateNoWindow = true;
build.ErrorDataReceived += build_ErrorDataReceived;
build.OutputDataReceived += build_ErrorDataReceived;
build.EnableRaisingEvents = true;
build.Start();
build.BeginOutputReadLine();
build.BeginErrorReadLine();
build.WaitForExit();
string findThis = "start";
int offset = 0;
foreach (string str in outputBuilder)
{
if (str.Contains("Duration"))
{
offset = str.IndexOf(findThis);
oStr = str.Substring(0, offset);
}
}
}
catch
{
oStr = "Error collecting file information";
}
return oStr;
}
private void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
string strMessage = e.Data;
if (outputBuilder != null && strMessage != null)
{
outputBuilder.Add(string.Concat(strMessage, "\n"));
}
}