///
/// DirectShow 视频播放 该方法以引用 DirectShowLib-2005.dll为基础
///
/// 视频文件路径
private void MediaRender(string fileName)
{
//全局时间轴
IAMTimeline m_pTimeline = (IAMTimeline)new AMTimeline();
#region 媒体三对象
IAMTimelineObj pGroupObj;
m_pTimeline.CreateEmptyNode(out pGroupObj, TimelineMajorType.Group);
IAMTimelineObj pTrackObj;
m_pTimeline.CreateEmptyNode(out pTrackObj, TimelineMajorType.Track);
IAMTimelineObj pSourceObj;
m_pTimeline.CreateEmptyNode(out pSourceObj, TimelineMajorType.Source);
#endregion
#region 组对象操作
AMMediaType m_pMediaType = GetVideoMediaType(24, 500, 400);
IAMTimelineGroup pGroup = (IAMTimelineGroup)pGroupObj;
pGroup.SetMediaType(m_pMediaType);//设轩播放组媒体类型
IAMTimelineComp pRootComp = (IAMTimelineComp)pGroupObj;
pRootComp.VTrackInsBefore(pTrackObj, 0); //在组中添加轨道
m_pTimeline.AddGroup(pGroupObj);//把组加到时间轴上
#endregion
#region 轨道操作
IAMTimelineTrack m_Track = (IAMTimelineTrack)pTrackObj;
m_Track.SrcAdd(pSourceObj); //将源添加到轨道
#endregion
#region 源操作
pSourceObj.SetStartStop(0, GetLength(fileName));//设置源的起止点
IAMTimelineSrc m_Src = (IAMTimelineSrc)pSourceObj;
m_Src.SetMediaName(fileName);//设置源文件
#endregion
#region 媒体引擎操作
IRenderEngine m_pRenderEngine = (IRenderEngine)new RenderEngine();
m_pRenderEngine.SetTimelineObject(m_pTimeline);//设置时间轴到引擎中
m_pRenderEngine.ConnectFrontEnd();//连结时间轴
#endregion
#region 图像生成器操作
IGraphBuilder m_pBuilder;
m_pRenderEngine.GetFilterGraph(out m_pBuilder);
#endregion
#region 图像捕获器操作
ICaptureGraphBuilder2 igcb = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
igcb.SetFiltergraph(m_pBuilder);
#endregion
#region 播放帧操作
IPin pin;
IAMTimelineObj pObj; //要播放的对象
m_pTimeline.GetGroup(out pObj, 0);
m_pRenderEngine.GetGroupOutputPin(0, out pin); //从播放引擎中获取播放帧
IBaseFilter ibfRender = (IBaseFilter)new VideoRenderer();//视频采集器
m_pBuilder.AddFilter(ibfRender, "");//从图形生成器中添加采集滤镜
IBaseFilter sempFilter = null;//临时流采集器
igcb.RenderStream(null, null, pin, sempFilter, ibfRender);//从视频采集器中产生视频流
#endregion
#region 窗体操作
IVideoWindow windows = (IVideoWindow)m_pBuilder;
windows.put_Owner(this.panel1.Handle);
windows.SetWindowPosition(panel1.ClientRectangle.Left, panel1.ClientRectangle.Top, panel1.ClientRectangle.Width, panel1.ClientRectangle.Height);
windows.put_WindowStyle(WindowStyle.Child|WindowStyle.ClipChildren);
windows.put_Caption("媒体播放");
#endregion
#region 媒体控件
IMediaControl control = (IMediaControl)m_pBuilder;//图像生成器以媒体控件的方式进行播放
control.Run();
#endregion
}
private long GetLength(String m_FileName)
{
int hr;
double d;
long i;
IMediaDet imd = (IMediaDet)new MediaDet();
// Set the name
hr = imd.put_Filename(m_FileName);
DESError.ThrowExceptionForHR(hr);
// Read from stream zero
hr = imd.put_CurrentStream(0);
DESError.ThrowExceptionForHR(hr);
// Get the length in seconds
hr = imd.get_StreamLength(out d);
DESError.ThrowExceptionForHR(hr);
Marshal.ReleaseComObject(imd);
// Convert to UNITS
i = (long)(d * (1000000000 / 100));
return i;
}
private AMMediaType GetVideoMediaType(short BitCount, int Width, int Height)
{
Guid mediaSubType;
AMMediaType VideoGroupType = new AMMediaType();
// Calculate the SubType from the Bit count
switch (BitCount)
{
case 16:
mediaSubType = MediaSubType.RGB555;
break;
case 24:
mediaSubType = MediaSubType.RGB24;
break;
case 32:
mediaSubType = MediaSubType.RGB32;
break;
default:
throw new Exception("Unrecognized bit format");
}
VideoGroupType.majorType = MediaType.Video;
VideoGroupType.subType = mediaSubType;
VideoGroupType.formatType = FormatType.VideoInfo;
VideoGroupType.fixedSizeSamples = true;
VideoGroupType.formatSize = Marshal.SizeOf(typeof(VideoInfoHeader));
VideoInfoHeader vif = new VideoInfoHeader();
vif.BmiHeader = new BitmapInfoHeader();
// The HEADER macro returns the BITMAPINFO within the VIDEOINFOHEADER
vif.BmiHeader.Size = Marshal.SizeOf(typeof(BitmapInfoHeader));
vif.BmiHeader.Compression = 0;
vif.BmiHeader.BitCount = BitCount;
vif.BmiHeader.Width = Width;
vif.BmiHeader.Height = Height;
vif.BmiHeader.Planes = 1;
int iSampleSize = vif.BmiHeader.Width * vif.BmiHeader.Height * (vif.BmiHeader.BitCount / 8);
vif.BmiHeader.ImageSize = iSampleSize;
VideoGroupType.sampleSize = iSampleSize;
VideoGroupType.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(vif));
Marshal.StructureToPtr(vif, VideoGroupType.formatPtr, false);
return VideoGroupType;
}