获取视频长度

Posted

技术标签:

【中文标题】获取视频长度【英文标题】:Getting length of video 【发布时间】:2011-09-07 02:17:31 【问题描述】:

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

有没有什么方法可以简单地做到这一点,无论是在 C#、python、java 中,它只会返回一个指示视频文件长度的字符串。

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

假设标准文件格式,例如 wmv、avi、mp4、mpeg。具有元数据的东西。

【问题讨论】:

答案取决于文件格式。没有一种工具可以返回有关您提供的任意视频文件的信息。 可以使用Alturos.VideoInfo。 【参考方案1】:

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

ffmpeg -i videofile.whatever

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

【讨论】:

【参考方案2】:

这是一个例子:

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;

【讨论】:

这对我来说非常有用,而且使用起来非常简单。不过,我确实注意到了一些小问题。似乎并非所有 .avi 文件都适用于此。也许它与视频文件的大小(> 1 GB)有关,但无论如何。它对我来说效果很好。感谢您的帮助! put_Filename 在我的机器上有 .mp4 文件的情况下会引发 COMException。它说:“DirectShowLib.dll 中发生‘System.Runtime.InteropServices.COMException’类型的未处理异常附加信息:指定了无效的媒体类型。” 声明 mediaType (= New) 的名称不应与 MediaType.Video 相同,这很混乱。 @user1801179,那是 10 年前的事了。您能否更新解决方案以使其不凌乱?【参考方案3】:

开源工具MediaInfo为媒体文件提供全面的元数据,可以在您自己的应用程序中以DLL形式使用easily:

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

【讨论】:

【参考方案4】:

我最近通过 ColdFusion 和 FFMpeg 的小表弟 FFProbe 找到了一个类似问题的解决方案……

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

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

不确定运行“ffprobe.exe -show_streams testFile”等价物的 C# 语法,但我相信一旦你弄清楚了,你就可以从收到的输出中解析出你需要的信息。

【讨论】:

【参考方案5】:

ffprobe 是来自 ffmpeg 项目的配套工具。除了提供各种文件格式的信息外,它还可以以 JSON 格式输出以方便解析。

查看answer 获取 JSON 输出示例。

【讨论】:

【参考方案6】:

我尝试以不同的方式获取视频长度: 实际上也使用 Windows Media Player 组件,我们可以得到视频的时长。 以下代码 sn-p 可以帮助你们:

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

并且不要忘记添加 wmp.dll 的引用,这将是 存在于 System32 文件夹中。

【讨论】:

【参考方案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);

【讨论】:

【参考方案8】:

如果使用 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

在这里回复是因为我偶然发现这篇文章正在寻找相同的东西 - 添加它以防万一它对任何人有帮助。

【讨论】:

以上是关于获取视频长度的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 getID3 获取长度视频

获取到目前为止录制的视频长度(或获取准确的开始时间)

flash as3.0获取外部视频总的时间长度 和视频已播放的时间长度

php获取视频长度,php.ini配置

上传前如何获取视频的元数据(长度)?

JS判断视频Video的播放暂停结束完成及获取长度事件监听处理