在項目中遇到過這樣的問題,就是如何在Winform中播放視頻。當時考察了幾種方式,第一種是直接使用Windows Media Player組件,這種最簡單;第二種是利用DirectX直接在窗體或者控件上繪圖,這種比較復雜。於是采用的是第一種方法。
先從VS的工具箱里添加Windows Media Player組件,方式是打開工具箱,在最下面的空白處點擊右鍵,選擇項,然后在彈出的對話框里切換到Com組件標簽項,找到“Windows Media Player”項並選中,確定后將在工具箱中看到多出一個圖標,然后就可以將這個圖標拖到窗體上進行設置了。
在這里主要講下,設置Windows Media Player組件時,有個屬性是“無窗口播放”,如果不啟用的話,在視頻播放時點擊鼠標的話,視頻會切換到全屏狀態,啟用就不會發生。但啟用的話,視頻的清晰度會下降很多(顆粒感變得很明顯),不啟用鼠標點擊又會放大。最初我采用定時將全屏屬性改為False來實現,時鍾設置成100毫秒或者更小,表現出來的就是用戶雙擊視頻后,屏蔽忽地一下變大然后又恢復原樣,更危險的是此操作有一定機率(而且不低)會將XP的任務欄暴露出來(因為我們的終端是要全屏顯示,不能讓用戶看到桌面及其它操作項的),於是我反復測試,最終采用的另外一種方式,即過濾窗體事件來直接屏蔽掉視頻區域的鼠標消息。具體實現如下:
先定義一個消息過濾類,用來屏蔽指定區域的鼠標雙擊或者單擊消息。然后在應用程序中加載此過濾器即可實現屏蔽消息功能。
public class MessageFilterMgr : IMessageFilter
{
Rectangle Rect;
public MessageFilterMgr(Rectangle rect)
{
Rect = rect;
}
public void Start()
{
Application.AddMessageFilter(this);
}
public void Stop()
{
Application.RemoveMessageFilter(this);
}
public bool PreFilterMessage(ref System.Windows.Forms.Message SystemMessage)
{
if (SystemMessage.Msg >= 513 && SystemMessage.Msg <= 515) //513|515是對應目標消息的值
{
if (Control.MousePosition.Y > Rect.Y && Control.MousePosition.Y < Rect.Y + Rect.Height
&& Control.MousePosition.X > Rect.X && Control.MousePosition.X < Rect.X + Rect.Width)
{
return true;
}
}
return false; //響應則為false
}
}
鼠標點擊問題已經解決,現在剩下最后一個問題了,就是如何實現視頻連續播放功能。開始我使用Window Media Player的狀態改變事件來控制,即當播放器的狀態改變時,發現它是停止狀態,馬上發送播放下一個視頻的指令,此種方法控制比較繁瑣,視頻之間停頓時間有點長(大約0.4秒的樣子)。后來改為使用播放列表,直接定義播放列表讓其自動循環播放。實現如下:
this.Player.settings.setMode("loop", true); // 將播放列表設置為循環播放
foreach (string item in this.Videos)
{
this.Player.currentPlaylist.appendItem(this.Player.newMedia(item)); // 將視頻逐個添加至播放列表
}
最后,我們的終端又要實現視頻與圖片混合播放功能,即視頻播放完畢后再播放圖片,我也將實現方式歸納如下:
在啟動時取消將播放列表的循環播放;
繼續利用播放組件的狀態改變事件,當播放器的狀態為wmppsReady(當播放列表中視頻數量大於1時)或者wmppsStopped(當播放列表中只有一個視頻時)時,表示播放已經完畢,然后將播放組件隱藏,再啟用圖片自動切換程序,等圖片切換完后,再將播放組件顯示,啟用播放。
另,默認狀態下,Windows Media Player支持的視頻格式很有限(最佳之選是WMV),想要支持更多的視頻格式,只能通過安裝視頻解碼器來實現。