0
我想为基于GMFBridge和DirectShow的视频播放器制作时间码计数器。我可以从directshow视频获取时间码吗?
我正在使用计时器每200ms调用一次GetCurrentPosition(),但我认为这不准确。我希望至少在视频运行时获取当前帧的帧号(从开始)。
这实际上可以做到吗?
我正在使用DirectShowLib .NET库。
我想为基于GMFBridge和DirectShow的视频播放器制作时间码计数器。我可以从directshow视频获取时间码吗?
我正在使用计时器每200ms调用一次GetCurrentPosition(),但我认为这不准确。我希望至少在视频运行时获取当前帧的帧号(从开始)。
这实际上可以做到吗?
我正在使用DirectShowLib .NET库。
据我所知,这是很难实现的,在一个解决方案,我对我的工作做了以下获得“帧数”:
// Get the media type from the SampleGrabber
AMMediaType media = new AMMediaType();
hr = sampGrabber.GetConnectedMediaType(media);
DsError.ThrowExceptionForHR(hr);
if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
{
throw new NotSupportedException("Unknown Grabber Media Format");
}
// Grab the size info
videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
DsUtils.FreeAMMediaType(media);
:
public int NumberOfFrames
{
get
{
return (int)(Duration/AverageTimePerFrame);
}
}
public double AverageTimePerFrame
{
get
{
return videoInfoHeader.AvgTimePerFrame/10000000.0;
}
}
public int GetCurrentFrame(double currentTime)
{
int noOfFrames = (int)(Duration/AverageTimePerFrame);
return Convert.ToInt32(Math.Min(noOfFrames - 1, Math.Floor(currentTime/AverageTimePerFrame)));
}
我做得到了VIDEOINFOHEADER
但是,这显然是适合我自己的用例,希望它可以帮助你一点点。祝你好运!
更新 新增CURRENTTIME代码(更衣室是我自己的使用情况,您可以最有可能删除):
public double CurrentTime
{
set
{
lock (locker)
{
IMediaPosition mediaPos = fFilterGraph as IMediaPosition;
int hr;
if (value >= 0 && value <= Duration)
{
hr = mediaPos.put_CurrentPosition(value);
DsError.ThrowExceptionForHR(hr);
}
}
}
get
{
lock (locker)
{
IMediaPosition mediaPos = fFilterGraph as IMediaPosition;
int hr;
double currentTime;
hr = mediaPos.get_CurrentPosition(out currentTime);
DsError.ThrowExceptionForHR(hr);
return currentTime;
}
}
}
感谢丹尼斯,你怎么currentTime的? – DaveO 2011-03-16 04:41:52
查看更新;-) – 2011-03-17 07:10:32
这个工作适合你DaveO? – 2011-03-19 02:28:40