C# 获取视频长度

C# 获取视频长度,c#,video,ffmpeg,duration,C#,Video,Ffmpeg,Duration,我很难找到一个简单的例子,说明如何通过编程获得文件的视频长度。许多人说,哦,使用这个库/包装器或其他什么,但不说如何使用。我已经下载了ffmpeg,但不知道如何实际使用它,而且似乎没有任何关于如何使用它来获取视频持续时间的示例。我知道如何使用它转换视频,但我只是想知道视频的持续时间。所有其他信息都无关紧要 有没有简单的方法可以做到这一点,不管是在C#、python、java还是其他语言中,都只会返回一个字符串来指示视频文件的长度 如果可能,请提供例子。提前谢谢 采用标准文件格式,如wmv、avi

我很难找到一个简单的例子,说明如何通过编程获得文件的视频长度。许多人说,哦,使用这个库/包装器或其他什么,但不说如何使用。我已经下载了ffmpeg,但不知道如何实际使用它,而且似乎没有任何关于如何使用它来获取视频持续时间的示例。我知道如何使用它转换视频,但我只是想知道视频的持续时间。所有其他信息都无关紧要

有没有简单的方法可以做到这一点,不管是在C#、python、java还是其他语言中,都只会返回一个字符串来指示视频文件的长度

如果可能,请提供例子。提前谢谢


采用标准文件格式,如wmv、avi、mp4、mpeg。有元数据的东西

通过使用-i标志,您可以获得多种视频格式的各种信息,包括ffmpeg的持续时间:

ffmpeg -i videofile.whatever
如果您想要一个漂亮的库,可以用C#为您包装ffmpef,那么您可以使用

以下是一个示例:

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;
使用DirectShowLib;
使用DirectShowLib.DES;
使用System.Runtime.InteropServices;
...
var mediaDet=(IMediaDet)new mediaDet();
DsError.ThrowExceptionForHR(mediaDet.put_文件名(Filename));
//在文件中查找视频流
整数指数;
var type=Guid.Empty;
对于(index=0;index<1000&&type!=MediaType.Video;index++)
{
mediaDet.put_CurrentStream(索引);
mediaDet.get_StreamType(输出类型);
}
//从视频中检索一些测量值
双帧率;
mediaDet.get_帧速率(输出帧速率);
var mediaType=新的AMMediaType();
mediaDet.get_StreamMediaType(mediaType);
var videoInfo=(VideoInfoHeader)Marshal.ptr结构(mediaType.formatPtr,typeof(VideoInfoHeader));
DsUtils.FreeAMMediaType(mediaType);
var width=videoInfo.BmiHeader.width;
var height=videoInfo.BmiHeader.height;
双中长;
mediaDet.get_StreamLength(输出mediaLength);
var frameCount=(int)(帧率*中间长度);
var duration=帧数/帧速率;
这个开源工具为媒体文件提供了全面的元数据,可以从您自己的应用程序中以DLL的形式使用:

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

我最近发现了一个类似问题的解决方案,与ColdFusion和FFMpeg的小表弟FFProbe一起

FFProbe有一个show_streams参数,它在返回的输出中推出初始流中的大量信息;包括视频的宽度、高度和持续时间


我不确定C#运行“ffprobe.exe-show#u streams testFile”等效程序的语法,但我确信一旦你弄明白了,你就可以从你收到的输出中解析出你需要的信息。

ffprobe是ffmpeg项目中的公司工具。除了提供各种文件格式的信息外,它还可以以JSON格式输出以简化解析


查看这个JSON输出的示例。

我尝试以一种稍微不同的方式获取视频长度:
实际上,我们也可以使用Windows Media Player组件来获取视频的持续时间。
以下代码片段可能会对你们有所帮助:

using WMPLib;
// ...
var player = new WindowsMediaPlayer();
var clip = player.newMedia(filePath);
Console.WriteLine(TimeSpan.FromSeconds(clip.duration));
不要忘记添加
wmp.dll的引用,它将
存在于
System32
文件夹中


我发现的最简单、最完美的解决方案是使用nuget软件包

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);
}
使用MediaToolkit;
//一种获取视频的宽度、高度和持续时间(以刻度为单位)的方法。
公共静态元组GetVideoInfo(字符串文件名)
{
var inputFile=new MediaToolkit.Model.MediaFile{Filename=Filename};
使用(变量引擎=新引擎())
{
engine.GetMetadata(inputFile);
}
//FrameSize返回为“1280x768”字符串。
var size=inputFile.Metadata.VideoData.FrameSize.Split(新[]{'x'})。选择(o=>int.Parse(o)).ToArray();
返回新元组(大小[0],大小[1],inputFile.Metadata.Duration.Ticks);
}

如果使用视频捕获对象,则可以使用Emgu.CV获取大量视频数据:

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
}

在这里回复是因为我无意中发现这篇文章在寻找同样的东西——添加它只是为了防止它对任何人都有帮助。

答案将取决于文件格式。没有一个工具可以返回任何你交给它的任意视频文件的信息。你可以使用它来获取视频的长度。这对我来说非常有用,而且使用非常简单。不过我确实注意到了一些小问题。似乎并不是所有的.avi文件都能处理这个问题。也许这与视频文件的大小有关(>1GB),但不管怎样。这对我很有效。谢谢你的帮助!如果我的计算机上有.mp4文件,请将\u文件名设置为异常。它说:“DirectShowLib.dll中发生“System.Runtime.InteropServices.COMException”类型的未处理异常。其他信息:指定了无效的媒体类型。“声明mediaType(=New)的名称不应与mediaType.Video的名称相同,这太糟糕了。@user1801179,这是10年前的事了。”。你能不能把解决方案更新一下,这样就不会乱七八糟了?