16

I am having trouble finding a simple example of how to get the video length of a file programmatically. Many people say, oh use this library/wrapper or whatever, but do not say how. I have downloaded ffmpeg, but have no clue how to actually use it and there does not seem to be any example of how to use it to get the video duration. I see how you can use it to convert videos, but I simply just want to know the duration of a video. All of the other information does not matter.

Is there any way of doing this simply, whether it be in C#, python, java, whatever, that will just return a string that indicates the length of a video file.

Please provide examples if possible. Thanks in advance!

Assume standard file formats, such as wmv, avi, mp4, mpeg. Stuff that has metadata.

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
MZimmerman6
  • 8,445
  • 10
  • 40
  • 70
  • 1
    The answer will depend on the file format. There's no one tool that will return information about any arbitrary video file you hand it. – Ernest Friedman-Hill Jun 02 '11 at 13:32
  • You can use [Alturos.VideoInfo](https://github.com/AlturosDestinations/Alturos.VideoInfo) to get the length of the video. – live2 Nov 02 '19 at 22:57

9 Answers9

15

Here is an example:

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;
nZeus
  • 2,475
  • 22
  • 21
  • 1
    this worked great for me and was very simple to use. I did notice some minor problems with it though. It seems that not all .avi files work with this. Maybe it had something to do with the size of the video file (> 1 GB) but whatever. It worked well for me. Thanks for your help! – MZimmerman6 Jun 04 '11 at 13:28
  • 3
    put_Filename throws COMException in case of .mp4 file on my machine. It says: "An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in DirectShowLib.dll Additional information: An invalid media type was specified." – EngineerSpock Jun 03 '17 at 19:01
  • You should not have same name for declaration mediaType (= New) as is MediaType.Video, that´s mess. – pyramidak Feb 23 '21 at 16:08
  • @user1801179, that's been 10 years ago. Could you maybe update the solution so that it's not messy? – nZeus Feb 24 '21 at 20:21
7

The easist and flawless solution I found is to use MediaToolkit nuget package.

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);
}
Youngjae
  • 24,352
  • 18
  • 113
  • 198
5

The open-source tool MediaInfo provides comprehensive meta-data for media files and can be used easily from your own application in DLL form:

void* Hande=MediaInfo::OpenQuick("**FILENAME**", "**VERSION**;**APP_NAME**;**APP_VERSION**")
MediaInfo::Inform()
rupello
  • 8,361
  • 2
  • 37
  • 34
2

I have tried to get the video length in a bit different way :
Actually using Windows Media Player Component also, we can get the duration of the video.
Following code snippet may help you guys :

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

and don't forget to add the reference of wmp.dll which will be present in System32 folder.

Rish
  • 1,303
  • 9
  • 22
1

ffprobe is companian tool from the ffmpeg project. Besides provinding information from a wide range of file formats, it can also ouput in a JSON format to ease the parsing.

Check this answer for an example of a JSON output.

Community
  • 1
  • 1
Paulo Fidalgo
  • 21,709
  • 7
  • 99
  • 115
1

you can get all sorts of information about many types of video formats including their duration with ffmpeg by using the -i flag:

ffmpeg -i videofile.whatever

If you want a nice library that can wrap ffmpef for you in C# then you can use MediaHandlerPro

Variant
  • 17,279
  • 4
  • 40
  • 65
0

I recently found a solution to a similar problem I had, with ColdFusion and FFMpeg's little cousin, FFProbe...

Is there a way to obtain the duration of a video file using ColdFusion?

FFProbe has a show_streams argument that pushes out a considerable amount of information in the initial stream within the returned output; including the width, height and duration of a video...

Not sure about C#'s syntax for running the equivalent of "ffprobe.exe -show_streams testFile" but I'm sure once you've figured that out, you can parse out the information you need from the output you receive.

Community
  • 1
  • 1
Eliseo D'Annunzio
  • 592
  • 1
  • 10
  • 26
0

You can use Emgu.CV to get a lot of video data if using a VideoCapture object:

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
}

Responding here because I stumbled across this post looking for the same thing - adding it just in case it helps anyone.

y3i
  • 13
  • 1
  • 5
0

Namaskaram,

One of the simplest ways is to use OpenCvSharp. It is allowed for commercial usage as well.

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 ;
}
AHATCHO
  • 1
  • 1