C# DirectShow 操作视频播放功能

///


/// 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;
 }

 

你可能感兴趣的:(C# DirectShow 操作视频播放功能)