获取视频长度

16

我在寻找一个简单的例子,来以编程方式获取视频文件长度,但是很难找到。许多人说要使用这个库/包装器之类的东西,却不说如何使用它们。我已经下载了FFmpeg,但是不知道该如何使用它,并且也没有任何关于如何使用它获取视频持续时间的示例。我知道如何使用它来转换视频,但我只是想知道视频的长度。其中所有其他信息都不重要。

是否有一种简单的方法来做到这一点,无论是C#,Python,Java还是其他什么语言,只需返回指示视频文件长度的字符串即可。

如果可能,请提供示例。先行致谢!

假设标准文件格式,如WMV,AVI,MP4,MPEG等具有元数据的格式。


1
答案将取决于文件格式。没有一个工具可以返回有关您提交的任意视频文件的信息。 - Ernest Friedman-Hill
你可以使用Alturos.VideoInfo来获取视频的长度。 - live2
9个回答

15

这里是一个例子:

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;

1
这对我非常有用,而且使用起来非常简单。不过我注意到了一些小问题。似乎并不是所有的.avi文件都能够使用它。也许与视频文件的大小(> 1 GB)有关,但无论如何,它对我很有效。感谢您的帮助! - MZimmerman6
3
在我的电脑上,put_Filename 在 .mp4 文件的情况下会抛出 COMException 异常。它显示:“在 DirectShowLib.dll 中发生了未处理的类型为 'System.Runtime.InteropServices.COMException' 的异常。额外信息:指定了无效的媒体类型。” - EngineerSpock
你不应该将声明的mediaType(= New)与MediaType.Video命名为相同的名称,这很混乱。 - pyramidak
@user1801179,那已经是10年前的事了。你能否更新解决方案,使其不再杂乱无章? - nZeus

7

我找到的最简单和无缝的解决方案是使用MediaToolkit 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);
}

5

这个开源工具MediaInfo提供了媒体文件的全面元数据,并且可以以DLL形式轻松地从你自己的应用程序中使用:

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

2

我试图用一种有点不同的方法获取视频长度:
实际上,我们也可以使用Windows Media Player组件来获取视频的持续时间。
以下代码片段可能会帮助大家:

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

并且不要忘记添加wmp.dll的引用,该文件位于System32文件夹中。

1

ffprobe是FFmpeg项目中的伴侣工具。除了提供各种文件格式的信息外,它还可以输出JSON格式以便于解析。

查看答案,了解JSON输出的示例。


1

使用-i标志,您可以通过ffmpeg获取有关许多类型视频格式的各种信息,包括它们的持续时间:

ffmpeg -i videofile.whatever

如果你想要一个能够在C#中为你封装ffmpef的好库,那么你可以使用MediaHandlerPro

请记住,如果您从另一个程序调用ffmpeg,则文本输出将发送到stderr而不是stdout。 - Steve Smith

0

我最近找到了一个解决方案,用于解决我在使用ColdFusion和FFMpeg的小兄弟FFProbe时遇到的类似问题...

有没有一种方法可以使用ColdFusion获取视频文件的持续时间?

FFProbe有一个show_streams参数,在返回的输出中推送出相当数量的信息,包括视频的宽度、高度和持续时间...

不确定C#的语法是否能够运行等效于"ffprobe.exe -show_streams testFile"的命令,但是我相信一旦你弄清楚了这个问题,就可以从接收到的输出中解析出所需的信息。


0

如果使用VideoCapture对象,您可以使用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
}

我在这里回复是因为我也在寻找同样的东西 - 只是为了帮助可能需要的人。


0

你好,

最简单的方法之一是使用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 ;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接