Sé que es muy tentador en C++ obtener un desglose adecuado de los archivos de video y simplemente hágalo usted mismo. Pero a pesar de que la información está disponible, es un proceso tan largo construir clases para entregar cada formato de archivo, y hacerlo fácilmente modificable para tener en cuenta los futuros cambios de estructura, que francamente no vale la pena el esfuerzo.
En lugar de eso, recomiendo ffmpeg. Recibió una mención anterior, pero dice que es difícil, no es difícil. Hay muchas más opciones de las que la mayoría de la gente necesitaría, lo que hace que parezca más difícil de lo que es. Para la mayoría de las operaciones, puedes dejar que ffmpeg lo resuelva solo.
Por ejemplo, una conversión de archivos ffmpeg -i inputFile.mp4 outputFile.avi
Decidir desde el principio que va a tener operaciones ffmpeg se ejecutan en un hilo, o más precisamente una biblioteca hilo.Pero haz que tu propia clase de subprocesos lo ajuste para que puedas tener tus propios EventAgs y los métodos para verificar el hilo hayan finalizado. Algo así como: -
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 ...
}
Aquí es un pequeño fragmento de mi clase de herramienta ffmpeg, esta parte la recopilación de información acerca de un vídeo. Pongo FFmpeg en una ubicación particular y, al inicio del software, se asegura de que esté allí. Para esta versión la he movido al escritorio, estoy bastante seguro de haber escrito la ruta correcta para ti (realmente odio el sistema de carpetas especiales de MS, así que lo ignoro tanto como puedo).
De todos modos, es un ejemplo del uso de ffmpeg sin ventana.
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"));
}
}