C # Получить длительность видео файла из метаданных - PullRequest
24 голосов
/ 10 августа 2009

Я пытаюсь прочитать метаданные из файла. Мне нужно только свойство Видео -> Длина, однако я не могу найти простой способ чтения этой информации.

Я подумал, что это будет довольно легко, так как это видно по умолчанию в Explorer, однако это выглядит намного сложнее, чем я ожидал. Ближайшее, что я нашел, использовало:

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

Однако это вызывает исключение LoaderLock, и я не знаю, как с этим справиться.

Есть идеи?

Ответы [ 11 ]

10 голосов
/ 16 августа 2009

Многие из этих сведений предоставляются оболочкой, поэтому вы можете сделать это, добавив ссылку на библиотеку COM «Элементы управления и автоматизации Microsoft Shell» (Shell32), а затем с помощью метода Folder.GetDetailsOf запросить расширенные сведения. ,

Я недавно искал это и наткнулся на этот самый вопрос на общих форумах MSDN C #. Я написал это как метод расширения для 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;
    }

Если вы ищете конкретные записи, вы можете сделать что-то подобное, хотя будет гораздо быстрее выяснить, по какому индексу находятся эти записи (я думаю, длина - это индекс 27) и просто запросить их. Заметьте, я мало исследовал, может ли индекс измениться (я сомневаюсь в этом), поэтому я выбрал словарь.

8 голосов
/ 11 августа 2009

Взгляните на этот вопрос SO - Solid FFmpeg-оболочка для C # /. NET , которая ссылается на несколько реализаций ffmpeg .Net. ffmpeg работает с большинством видеоформатов / кодеков. Таким образом, вам не нужно беспокоиться об установке кодека на компьютере.

Или посмотрите на http://mediainfo.sourceforge.net/en.

3 голосов
/ 13 августа 2009

Я бы только прокомментировал пост Микаэля, но у меня пока недостаточно представителей, чтобы сделать это. Я согласен с ним в использовании ffmpeg, чтобы вам не требовалось устанавливать кодеки. Вы можете просто проанализировать вывод "ffmpeg -i your_filename", который просто выдаст некоторую информацию о видео, включая продолжительность.

Я не знаю, с какими кодеками вы работаете, но некоторые контейнеры на самом деле не хранят длительность в метаданных (это обычно для потоковых контейнеров, так как длительность неизвестна). Я не знаю, как ffmpeg справляется с этим, но, похоже, это как-то находит (может быть, анализируя весь файл для временных кодов).

2 голосов
/ 23 февраля 2017

Я рекомендую использовать MediaToolkit пакет nuget. Не требует COM-взаимодействия с вашим кодом.

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);
}
1 голос
/ 27 августа 2014

Получение продолжительности видеофайла в Win Rt App или Metro C #:

StorageFile videoFile;
videoFile = await StorageFile.GetFileFromPathAsync(VIDEO_PATH_HERE);
Windows.Storage.FileProperties.VideoProperties x = await videoFile.Properties.GetVideoPropertiesAsync();
var videoDuration = x.Duration;
1 голос
/ 18 мая 2010

с использованием 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;
        }
    }
0 голосов
/ 29 июня 2019

Вы можете использовать нашу оболочку для ffprobe Alturos.VideoInfo . Вы можете использовать его, просто установив пакет nuget. Также требуется двоичный файл ffprobe .

PM> install-package Alturos.VideoInfo

Пример

var videoFilePath = "myVideo.mp4";

var videoAnalyer = new VideoAnalyzer("ffprobe.exe");
var videoInfo = videoAnalyer.GetVideoInfo(videoFilePath);

//Video length
var duration = videoInfo.Format.Duration;
0 голосов
/ 16 ноября 2017

Кажется, я публикую то, что пытался, так поздно. Надеюсь, это кому-нибудь поможет.

Я попытался немного увеличить длину видео, воспользовавшись компонентом проигрывателя Windows Media. Следующий фрагмент кода может помочь вам, ребята:

using WMPLib;
// ...your code here...

var player = new WindowsMediaPlayer();
var clip = player.newMedia(filePath);
Console.WriteLine(TimeSpan.FromSeconds(clip.duration));

и не забудьте добавить ссылку wmp.dll, которая будет присутствует в папке System32.

0 голосов
/ 23 декабря 2011

использование MCI

это простой в использовании и работает даже на 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
0 голосов
/ 19 августа 2009

У меня была такая же проблема с небольшим приложением для предварительного просмотра видео.

Проблема в управляемых помощниках отладки. Эта проблема возникает при использовании библиотек Managed DirectX 1.1 в VS2005 или 2008. Microsoft перешла на работу с MDX2, а затем с XNA, а не с Managed DirectX 1, поэтому не надейтесь слишком много на патч.

Простой обходной путь - отключить обработку исключений LoaderLock при отладке этого решения. В любом случае это не должно иметь реального влияния на программу, поскольку эта ошибка появляется только в среде отладки.

Чтобы отключить, перейдите в Debug -> Exceptions -> Managed Debugging Assistants и снимите флажок LoaderLock.

Подробнее здесь: http://vivekthangaswamy.blogspot.com/2006/11/loaderlock-was-detected-error-when.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...