C # Ottieni la durata del file video dai metadati

Sto cercando di leggere i metadati da un file. Ho solo bisogno della proprietà Video -> Lunghezza, tuttavia non riesco a trovare un modo semplice di leggere queste informazioni.

Ho pensato che sarebbe stato abbastanza facile dato che è visibile di default in Explorer, tuttavia sembra molto più complicato di quanto immaginassi. Il più vicino che sono venuto stava usando:

Microsoft.DirectX.AudioVideoPlayback.Video video = new Microsoft.DirectX.AudioVideoPlayback.Video(str); double duration = video.Duration; 

Tuttavia ciò genera un’eccezione LoaderLock e non so come gestirla.

Qualche idea?

Molti di questi dettagli sono forniti dalla shell, quindi è ansible farlo aggiungendo un riferimento alla libreria COM “Controlli e automazione della shell Microsoft” (Shell32) e quindi utilizzando il metodo Folder.GetDetailsOf per interrogare i dettagli estesi.

Recentemente lo stavo cercando e mi sono imbattuto in questa stessa domanda sui forum di MSDN C # General. Ho finito per scrivere questo come un metodo di estensione per FileInfo:

  public static Dictionary GetDetails(this FileInfo fi) { Dictionary ret = new Dictionary(); 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; } 

Se stai cercando voci specifiche, puoi fare qualcosa di simile, anche se sarà molto più veloce scoprire quale indice sono quelle voci (lunghezza è indice 27 credo) e basta interrogarle. Nota, non ho fatto molte ricerche sul fatto che l'indice possa cambiare o meno (ne dubito), ed è per questo che ho adottato l'approccio del dizionario.

Dai un’occhiata a questa domanda SO: Solid FFmpeg wrapper per C # /. NET che si collega a diverse implementazioni ffmpeg .Net. ffmpeg funziona con la maggior parte dei formati / codec video. In questo modo non è necessario preoccuparsi del codec installato sulla macchina.

Oppure guarda http://mediainfo.sourceforge.net/en .

Avrei solo commentato il post di Mikael, ma non ho ancora abbastanza rep per farlo ancora. Sono d’accordo con lui sull’uso di ffmpeg in modo da non dover richiedere l’installazione dei codec. Potresti solo analizzare l’output di “ffmpeg -i your_filename” che scaricherà alcune informazioni sul video, inclusa la durata.

Non conosco i codec con cui stai lavorando, ma alcuni contenitori non memorizzano effettivamente la durata nei metadati (questo è comune ai contenitori di streaming poiché la durata è sconosciuta). Non so come ffmpeg gestisca questo, ma sembra trovarlo in qualche modo (magari analizzando l’intero file per i timecode).

Consiglio di utilizzare il pacchetto nuget di MediaToolkit. Non richiede l’interoperabilità COM sul tuo codice.

 using MediaToolkit; // a method to get Width, Height, and Duration in Ticks for video. public static Tuple 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(size[0], size[1], inputFile.Metadata.Duration.Ticks); } 

utilizzando DirectShowLib ( http://directshownet.sourceforge.net/ )

  ///  /// Gets the length of the video. ///  /// Name of the file. /// The length. ///  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; } } 

MediaInfo è una grande libreria open source per questo scopo (la DLL è licenziata LGPL). Il pacchetto di download contiene un’applicazione di esempio in C # (in Developers\Project\MSCS\Example )

Ho avuto lo stesso problema con una piccola app di anteprima video.

Il problema è Managed Debugging Assisstants. Questo è un problema quando si utilizzano le librerie Managed DirectX 1.1 in VS2005 o 2008. Microsoft ha spostato l’attenzione su MDX2 e quindi su XNA anziché su DirectX 1, quindi non sperare troppo in una patch.

La soluzione facile è disabilitare la gestione dell’eccezione LoaderLock durante il debug di tale soluzione. Questo non dovrebbe avere alcun effetto reale sul programma in ogni caso poiché questo errore si presenta solo in un ambiente di debug.

Per disabilitare andare su Debug -> Eccezioni -> Assistenti debug gestiti e deselezionare LoaderLock.

Maggiori informazioni qui: http://vivekthangaswamy.blogspot.com/2006/11/loaderlock-was-detected-error-when.html

usa MCI

è facile da usare e funziona anche su 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 

ottenere la durata del file video in Win Rt App o Metro C #

File di memoria File video; string path = ApplicationData.Current.LocalFolder.Path; videoFile = attende StorageFile.GetFileFromPathAsync (presentationItem.Slide_path_local); Windows.Storage.FileProperties.VideoProperties x = attende videoFile.Properties.GetVideoPropertiesAsync (); Durata videoDuration = x.Duration;

Sembra che sto postando, quello che ho provato, così tardi. Spero che aiuti qualcuno.

Ho cercato di ottenere la lunghezza del video in un modo leggermente diverso cantando Windows Media Player Component.
Il seguente snippet di codice potrebbe aiutarti a:

 using WMPLib; // ...your code here... var player = new WindowsMediaPlayer(); var clip = player.newMedia(filePath); Console.WriteLine(TimeSpan.FromSeconds(clip.duration)); 

e non dimenticare di aggiungere il riferimento di wmp.dll che sarà presente nella cartella System32 .