online - C#Obtener la duración del archivo de vídeo a partir de metadatos
metapicz (10)
Estoy tratando de leer los metadatos de un archivo. Solo necesito la propiedad Video -> Length, pero no puedo encontrar una forma sencilla de leer esta información.
Pensé que esto sería bastante fácil ya que es visible de forma predeterminada en el Explorador, sin embargo, parece ser mucho más complicado de lo que esperaba. Lo más cerca que vine fue usando:
Microsoft.DirectX.AudioVideoPlayback.Video video = new Microsoft.DirectX.AudioVideoPlayback.Video(str);
double duration = video.Duration;
Sin embargo, esto genera una excepción LoaderLock, y no sé cómo lidiar con ella.
¿Algunas ideas?
Eche un vistazo a esta pregunta SO: envoltorio sólido de FFmpeg para C # / .NET que enlaza con varias implementaciones de .ffmpeg .Net. ffmpeg funciona con la mayoría de los formatos de video / codecs. De esa manera, no necesita preocuparse por el códec que se instala en la máquina.
O mira en http://mediainfo.sourceforge.net/en .
El shell proporciona muchos de estos detalles, por lo que puede hacer esto agregando una referencia a la biblioteca de COM "Microsoft Shell Controls and Automation" (Shell32), y luego usando el método Folder.GetDetailsOf para consultar los detalles extendidos.
Hace poco estuve buscando esto y encontré esta pregunta en los foros generales de C # de MSDN. Terminé escribiendo esto como un método de extensión a FileInfo:
public static Dictionary<string, string> GetDetails(this FileInfo fi)
{
Dictionary<string, string> ret = new Dictionary<string, string>();
Shell shl = new ShellClass();
Folder folder = shl.NameSpace(fi.DirectoryName);
FolderItem item = folder.ParseName(fi.Name);
for (int i = 0; i < 150; i++)
{
string dtlDesc = folder.GetDetailsOf(null, i);
string dtlVal = folder.GetDetailsOf(item, i);
if (dtlVal == null || dtlVal == "")
continue;
ret.Add(dtlDesc, dtlVal);
}
return ret;
}
Si está buscando entradas específicas, puede hacer algo similar, aunque será mucho más rápido averiguar en qué índice están esas entradas (la Longitud es el índice 27, creo) y solo consultarlas. Tenga en cuenta que no hice mucha investigación sobre si el índice puede cambiar (lo dudo), razón por la cual adopté el enfoque del diccionario.
Habría comentado la publicación de Mikael, pero todavía no tengo suficiente representante para hacerlo. Estoy de acuerdo con él en usar ffmpeg para que no tenga que solicitar que se instalen los codecs. Puedes simplemente analizar la salida de "ffmpeg -i tu_nombre_de_archivo", que simplemente descargará algo de información sobre el video, incluida la duración.
No sé con qué códecs está trabajando, pero algunos contenedores no almacenan realmente la duración en los metadatos (esto es común en los contenedores de transmisión, ya que la duración es desconocida). No sé cómo ffmpeg maneja esto, pero parece encontrarlo de alguna manera (tal vez analizando el archivo completo para los códigos de tiempo).
Obtención de la duración del archivo de video en Win Rt App o Metro C #
StorageFile videoFile; string path = ApplicationData.Current.LocalFolder.Path; videoFile = aguarda StorageFile.GetFileFromPathAsync (presentationItem.Slide_path_local); Windows.Storage.FileProperties.VideoProperties x = aguarda videoFile.Properties.GetVideoPropertiesAsync (); Duración videoDuration = x.Duration;
Parece que estoy publicando, lo que he intentado, tan tarde. Espero que ayude a alguien.
He intentado obtener la duración del video de una manera un poco diferente al cantar Windows Media Player Component.
El siguiente fragmento de código puede ayudarlos a ustedes:
using WMPLib;
// ...your code here...
var player = new WindowsMediaPlayer();
var clip = player.newMedia(filePath);
Console.WriteLine(TimeSpan.FromSeconds(clip.duration));
y no olvide agregar la referencia de
wmp.dll
que estará presente en la carpetaSystem32
.
Recomiendo usar el paquete MediaToolkit MediaToolkit. No requiere interoperabilidad COM en su código.
using MediaToolkit;
// a method to get Width, Height, and Duration in Ticks for video.
public static Tuple<int, int, long> GetVideoInfo(string fileName)
{
var inputFile = new MediaToolkit.Model.MediaFile { Filename = fileName };
using (var engine = new Engine())
{
engine.GetMetadata(inputFile);
}
// FrameSize is returned as ''1280x768'' string.
var size = inputFile.Metadata.VideoData.FrameSize.Split(new[] { ''x'' }).Select(o => int.Parse(o)).ToArray();
return new Tuple<int, int, long>(size[0], size[1], inputFile.Metadata.Duration.Ticks);
}
Tuve el mismo problema con una pequeña aplicación de vista previa de video.
El problema es Managed Debugging Assisstants. Este es un problema cuando se usan las bibliotecas Managed DirectX 1.1 en VS2005 o 2008. Microsoft se ha centrado en MDX2 y luego en XNA en lugar de Managed DirectX 1, así que no esperes demasiado para un parche.
La solución sencilla es deshabilitar el manejo de excepciones de LoaderLock mientras se depura esa solución. Esto no debería tener ningún efecto real en el programa, ya que este error solo aparece en un entorno de depuración.
Para deshabilitar, vaya a Depurar -> Excepciones -> Asistentes de depuración administrados y desmarque LoaderLock.
Más información aquí: http://vivekthangaswamy.blogspot.com/2006/11/loaderlock-was-detected-error-when.html
usar MCI
Es fácil de usar y funciona incluso en NT:
using System.Runtime.InteropServices;
[DllImport("winmm.dll")]
public static extern int mciSendString(string lpstrCommand, StringBuilder lpstrReturnString, int uReturnLength, int hwndCallback);
[DllImport("winmm.dll")]
private static extern int mciGetErrorString(int l1, StringBuilder s1, int l2);
string cmd = "open " + strFile + " alias video";
StringBuilder mssg = new StringBuilder(255);
int h = mciSendString(cmd, null, 0, 0); // open video at mci
int i = mciSendString("set video time format ms", null, 0, 0); // set time format, you can see other formats at link above
int j = mciSendString("status video length", mssg, mssg.Capacity, 0); //get video length into mssg
Console.WriteLine(mssg.ToString());
int m = mciSendString("close video", null, 0, 0); //close video
utilizando DirectShowLib ( http://directshownet.sourceforge.net/ )
/// <summary>
/// Gets the length of the video.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="length">The length.</param>
/// <returns></returns>
static public bool GetVideoLength(string fileName, out double length)
{
DirectShowLib.FilterGraph graphFilter = new DirectShowLib.FilterGraph();
DirectShowLib.IGraphBuilder graphBuilder;
DirectShowLib.IMediaPosition mediaPos;
length = 0.0;
try
{
graphBuilder = (DirectShowLib.IGraphBuilder)graphFilter;
graphBuilder.RenderFile(fileName, null);
mediaPos = (DirectShowLib.IMediaPosition)graphBuilder;
mediaPos.get_Duration(out length);
return true;
}
catch
{
return false;
}
finally
{
mediaPos = null;
graphBuilder = null;
graphFilter = null;
}
}
http://mediainfo.sourceforge.net/en es una excelente biblioteca de código abierto para ese propósito (la DLL tiene licencia LGPL). El paquete de descarga contiene una aplicación de ejemplo en C # (en Developers/Project/MSCS/Example
)