Получение продолжительности видео

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

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

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

Предположим, стандартные форматы файлов, такие как WMV, AVI, MP4, MPEG. Материал с метаданными.

9 ответов

Решение

Вот пример:

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;

Простое и безупречное решение, которое я нашел, заключается в использовании пакета 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);
}

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

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

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

ffmpeg -i videofile.whatever

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

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

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

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

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

Проверьте этот ответ для примера вывода JSON.

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

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

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

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

Намаскарам,

Один из самых простых способов — использовать OpenCvSharp . Разрешено и коммерческое использование.

      using OpenCvSharp;
                
void GetVideoDuration()
{
   VideoCapture vidCapture = new VideoCapture(videoClipPath);
        
   var totalFrameCount = vidCapture.Get(VideoCaptureProperties.FrameCount);
        
   var framesPerSecond = vidCapture.Get(VideoCaptureProperties.Fps);
         
   var videoDurationInSeconds = totalFrameCount/framesPerSecond ;
}

Вы можете использовать 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
}

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

Другие вопросы по тегам