Получение длины видео

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

Есть ли способ сделать это просто, будь то C #, python, java или что угодно, это просто вернет строку, указывающую длину видеофайла.

Если возможно, приведите примеры. Заранее спасибо!

Предположим, стандартные форматы файлов, такие как wmv, avi, mp4, mpeg. Материал с метаданными.


person MZimmerman6    schedule 02.06.2011    source источник
comment
Ответ будет зависеть от формата файла. Нет ни одного инструмента, который вернул бы информацию о любом произвольном видеофайле, который вы ему передали.   -  person Ernest Friedman-Hill    schedule 02.06.2011
comment
Вы можете использовать Alturos.VideoInfo, чтобы узнать длину видео.   -  person live2    schedule 03.11.2019


Ответы (8)


Вот пример:

using DirectShowLib;
using DirectShowLib.DES;
using System.Runtime.InteropServices;

...

var mediaDet = (IMediaDet)new MediaDet();
DsError.ThrowExceptionForHR(mediaDet.put_Filename(FileName));

// find the video stream in the file
int index;
var type = Guid.Empty;
for (index = 0; index < 1000 && type != MediaType.Video; index++)
{
    mediaDet.put_CurrentStream(index);
    mediaDet.get_StreamType(out type);
}

// retrieve some measurements from the video
double frameRate;
mediaDet.get_FrameRate(out frameRate);

var mediaType = new AMMediaType();
mediaDet.get_StreamMediaType(mediaType);
var videoInfo = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));
DsUtils.FreeAMMediaType(mediaType);
var width = videoInfo.BmiHeader.Width;
var height = videoInfo.BmiHeader.Height;

double mediaLength;
mediaDet.get_StreamLength(out mediaLength);
var frameCount = (int)(frameRate * mediaLength);
var duration = frameCount / frameRate;
person nZeus    schedule 02.06.2011
comment
это отлично сработало для меня и было очень простым в использовании. Однако я заметил некоторые незначительные проблемы с ним. Похоже, не все файлы .avi с этим работают. Может быть, это как-то связано с размером видеофайла (›1 ГБ), но неважно. У меня это сработало. Спасибо за вашу помощь! - person MZimmerman6; 04.06.2011
comment
put_Filename выбрасывает COMException в случае файла .mp4 на моем компьютере. В нем говорится: в DirectShowLib.dll возникло необработанное исключение типа System.Runtime.InteropServices.COMException. Дополнительная информация: указан недопустимый тип носителя. - person SaneDeveloper; 03.06.2017
comment
У вас не должно быть того же имени для объявления mediaType (= New), как у MediaType.Video, это беспорядок. - person user1801179; 23.02.2021
comment
@ user1801179, это было 10 лет назад. Не могли бы вы обновить решение, чтобы оно не было беспорядочным? - person nZeus; 24.02.2021

Я нашел простое и безупречное решение - использовать пакет nuget MediaToolkit.

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);
}
person Youngjae    schedule 23.02.2017

Инструмент с открытым исходным кодом MediaInfo предоставляет исчерпывающие метаданные для медиафайлов и может использоваться легко из вашего собственного приложения в форме DLL:

void* Hande=MediaInfo::OpenQuick("**FILENAME**", "**VERSION**;**APP_NAME**;**APP_VERSION**")
MediaInfo::Inform()
person rupello    schedule 02.06.2011

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

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

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

person Rish    schedule 02.09.2016

вы можете получить всевозможную информацию о многих типах видеоформатов, включая их продолжительность, с помощью ffmpeg, используя флаг -i:

ffmpeg -i videofile.whatever

Если вам нужна хорошая библиотека, которая может обернуть для вас ffmpef на C #, вы можете использовать MediaHandlerPro

person Variant    schedule 02.06.2011

ffprobe - это вспомогательный инструмент из проекта ffmpeg. Помимо получения информации из широкого диапазона форматов файлов, он также может выводить данные в формате JSON для облегчения анализа.

Посмотрите этот ответ, чтобы увидеть пример вывода JSON.

person Paulo Fidalgo    schedule 29.05.2013

Недавно я нашел решение похожей проблемы с помощью ColdFusion и маленького кузена FFMpeg, FFProbe ...

Есть ли способ узнать продолжительность видеофайла с помощью ColdFusion?

FFProbe имеет аргумент show_streams, который выталкивает значительный объем информации из начального потока в возвращаемый результат; включая ширину, высоту и продолжительность видео ...

Не уверен в синтаксисе C # для запуска эквивалента «ffprobe.exe -show_streams testFile», но я уверен, что как только вы это выясните, вы сможете проанализировать нужную информацию из полученного вами вывода.

person Eliseo D'Annunzio    schedule 18.02.2013

Вы можете использовать Emgu.CV для получения большого количества видеоданных, если используете объект VideoCapture:

using Emgu.CV;
using (var video = new VideoCapture(path)) 
{
   double fc = (int)Math.Floor(video.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameCount));
   // frame count
   double fps = video.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps);
   // fps
   double length = fc / fps;
   // length in seconds
}

Отвечаю здесь, потому что наткнулся на этот пост в поисках того же самого - добавил на всякий случай, если он кому-то поможет.

person y3i    schedule 16.12.2020