原文網址:http://blog.csdn.net/openzpc/article/details/48442751
最近在開發一個視頻播放軟件,主要要求就是循環播放多個視頻文件,並且要求兩個視頻文件切換時,不能有黑屏現象發生。
無論是使用Winform的Mediaplayer控件還是WPF的MediaElement控件,在一個視頻播放完畢切換到另一個視頻時,都會有一個短暫的黑屏情況,於是我就把目光放在了DirectShow上面。下面說一下如何使用DirectShow進行視頻播放。
1.quartz.dll和Tlbimp.exe
使用DirectShow,需要用到C:\Windows\System32文件夾下的quartz.dll文件,但此文件並不能直接在Visual Studio中使用,需要通過Tlbimp.exe(類型庫導入程序),將quartz.dll轉化為互操作程序集。這里只需要執行以下命令
- tlbimp c:\windows\system32\quartz.dll /out:QuartzTypeLib.dll
這個命令並不是直接在cmd中執行,而是在Vs的開發工具中。
執行結果如下
2.相關代碼
首先創建FilgraphManager等相關的實例
- private const int WM_APP = 0x8000;
- private const int WM_GRAPHNOTIFY = WM_APP + 1;
- FilgraphManager _filGraphManager = null;
- private IBasicVideo _basicVideo = null;
- IVideoWindow _videoWindow = null;
- IMediaEvent _mediaEvent = null;
- IMediaEventEx _mediaEventEx = null;
- IMediaPosition _mediaPosition = null;
- IMediaControl _mediaControl = null;
加載視頻文件
- private void LoadVideo(string fileName)
- {
- _filGraphManager = new FilgraphManager();
- _filGraphManager.RenderFile(fileName);
- _basicVideo = _filGraphManager as IBasicVideo;
- try
- {
- _videoWindow = _filGraphManager as IVideoWindow;
- _videoWindow.Owner = (int) PlVideo.Handle;
- _videoWindow.WindowStyle = 0x40000000;
- _videoWindow.SetWindowPosition(PlVideo.ClientRectangle.Left, PlVideo.ClientRectangle.Top,
- PlVideo.ClientRectangle.Width, PlVideo.ClientRectangle.Height);
- }
- catch (Exception)
- {
- throw;
- }
- _mediaEvent = _filGraphManager as IMediaEvent;
- _mediaEventEx = _filGraphManager as IMediaEventEx;
- _mediaEventEx.SetNotifyWindow((int) this.Handle, WM_GRAPHNOTIFY, 0);
- _mediaPosition = _filGraphManager as IMediaPosition;
- _mediaControl = _filGraphManager as IMediaControl;
- }
視頻播放只需要調用FilgraphManager實例中的Run方法即可
3.類和接口的說明
FilgraphManager 用於建立和控制graph的對象
RenderFile方法用於加載指定文件,Run,Stop,Pause方法對filters進行控制
IBasicVideo 接口 設置video的屬性,如寬高,比特率等內容,通過owner屬性設置video在哪個控件上顯示
IMediaEvent 接口 獲取事件通知的接口 IMediaEventEx是前者的擴展
IMediaPosition 接口 用於獲取stream中的位置 get_CurrentPosition方法可以獲取當前位置,當需要進度條顯示視頻播放位置時,可以使用此方法
IMediaControl 接口 這個根據名稱就可以知道用途