获取视频长度
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
在这里回复是因为我偶然发现这篇文章正在寻找相同的东西 - 添加它以防万一它对任何人有帮助。
【讨论】:
以上是关于获取视频长度的主要内容,如果未能解决你的问题,请参考以下文章