基於WMP控件編程(屬性)

http://blog.csdn.net/kingmax54212008/article/details/7178495


windows media player 控件在我們編程時經常要用到,但是有很多屬性及方法卻不知道該怎麼使用。現以 wmp 9.0控件爲例說說其常用的屬性與方法.

 

 

屬性/方法名: 說明:
[基本屬性]  
URL:String; 指定媒體位置,本機或網絡地址
uiMode:String; 播放器界面模式,可爲Full, Mini, None, Invisible
playState:integer; 播放狀態,1=停止,2=暫停,3=播放,6=正在緩衝,9=正在連接,10=準備就緒
enableContextMenu:Boolean; 啓用/禁用右鍵菜單
fullScreen:boolean; 是否全屏顯示
[controls] wmp.controls //播放器基本控制
controls.play; 播放
controls.pause; 暫停
controls.stop; 停止
controls.currentPosition:double; 當前進度
controls.currentPositionString:string; 當前進度,字符串格式。如“00:23”
controls.fastForward; 快進
controls.fastReverse; 快退
controls.next; 下一曲
controls.previous; 上一曲
[settings] wmp.settings //播放器基本設置
settings.volume:integer; 音量,0-100
settings.autoStart:Boolean; 是否自動播放
settings.mute:Boolean; 是否靜音
settings.playCount:integer; 播放次數
[currentMedia] wmp.currentMedia //當前媒體屬性
currentMedia.duration:double; 媒體總長度
currentMedia.durationString:string; 媒體總長度,字符串格式。如“03:24”
currentMedia.getItemInfo(const string); 獲取當前媒體信息"Title"=媒體標題,"Author"=藝術家,"Copyright"=版權信息,"Description"=媒體內容描述,"Duration"=持續時間(秒),"FileSize"=文件大小,"FileType"=文件類型,"sourceURL"=原始地址
currentMedia.setItemInfo(const string); 通過屬性名設置媒體信息
currentMedia.name:string; 同 currentMedia.getItemInfo("Title")
[currentPlaylist] wmp.currentPlaylist //當前播放列表屬性
currentPlaylist.count:integer; 當前播放列表所包含媒體數
currentPlaylist.Item[integer]; 獲取或設置指定項目媒體信息,其子屬性同wmp.currentMedia

 

 

Media player控件基本使用步驟如下:
一、往控件箱中添加此控件:wmp.dll
二、往窗體上拖控件
三、wmp.URL=XXXX;wmp.play()即可。
平常應用就這三步就OK了。但是,我想寫個播放器的話,就遇到了一些問題。
在 dotnet中使用非基於dotnet的控件,需要做一些額外的事,不過這些事vs已經幫我們做好了,當我們拖了此控件進窗體時,vs會自動調用 AxImp.exe,用它根據原有的dll或ocx生成一個用AxHost類包裝的新的一組程序集(更爲精確的描述見msdn),於是根據 WMPLib.dll生成兩個文件:AxInterop.WMPLib.dll、Interop.WMPLib.dll。這兩個文件中包含了轉化後的類。 包裝後的控件繼承自System.Windows.Forms.AxHost。
這是第一個問題,控件怎麼使用呢?如果是拖控件,很簡單,無論如何都能有效的使用。但是,如果手工new創建控件的實例呢?那就不一定了。
我做過種種實驗,獲得如下的結論:
在非可視化類中無法創建有UI的控件的實例,或者是在沒有把實例加入到一個可視化的容器中時。
我實驗了下面的代碼:
       AxWMPLib.AxWindowsMediaPlayer wmp = new AxWMPLib.AxWindowsMediaPlayer();
       this.Controls.Add(wmp);
       wmp.URL = "約定.mp3";
       wmp.Ctlcontrols.play();
這 幾行代碼不一定能運行。發現,如果這幾行代碼寫在窗體的構造函數中,哪怕show出來都不能運行,只有寫在Load或Load之後的事件中,並且把窗 體show出來纔有運行,否則會拋出一個錯誤:引發類型爲“System.Windows.Forms.AxHost+ InvalidActiveXStateException”的異常。網上有些人也遇到這個問題,其實都沒有談到點子上。甚爲遺憾。
是不是不show就一定不能運行呢?我拖了個播放器控件放窗體上,在InitializeComponent後面寫了行play的代碼,能運行。可見,這中間有蹊蹺啊。我比較了上面的代碼跟拖上去生成的代碼,有兩點不同:
一、拖控件生成的代碼爲多一對((System.ComponentModel.ISupportInitialize)(this.wmp1)).BeginInit()/EndInit()
二、 拖的控件多了一行:this.wmp1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("wmp1.OcxState"))); 我查了MSDN,ocxstate是控件狀態。用於持久化控件的狀態的。com組件的狀態信息被寫在對應窗體的資源文件中,用記事本打開窗體資源文件就可 以看到。在手工創建中,這個ocxstate是沒法賦值的。
我試了加入BeginInit、EndInit,沒用,可見問題是出在控件狀態問題上。沒有辦法了。

取當前播放媒體的信息,這個很簡單,currentMedia就可以取得。怎樣創建播放列表呢?讓播放器依次播放指定的媒體呢?有辦法,我自己摸索出來的:
wmp1.currentPlaylist.appendItem(wmp1.newMedia("約定.mp3"))
我看到網上的兄弟不曉得用currentPlaylist,在自己實現播放列表,我覺得沒必要。
鬱 悶無比,用wmp播放rmvb等非默認支持文件時,會彈出錯誤消息框,儘可以用一個屬性 wmp.settings.enableErrorDialogs=false控制它不顯示,但是,還是有一個後遺症,就是調用 wmp.Ctlcontrols.play()時,它並不會播放,但是單擊一下自帶播放控制欄中的三角行按鈕就能播放了。鬱悶啊。
我又去的了暴風3的mps.dll。果然,它用的是酷熱影音的內核。不過,酷熱提供的這個控件實在太差勁了。沒什麼高級功能。鬱悶。還是wmp好啊。繼續研究wmp。我現在裝的是wmp11。
現在又找到一些更全的關於wmp API的資料,如下:
屬性/方法名說明:
詳盡的API文檔(比MSDN更透徹):
[基本屬性]  
URL:String; 指定媒體位置,本機或網絡地址
uiMode:String; 播放器界面模式,可爲Full, Mini, None, Invisible(不計大小寫)
playState:integer; 播放狀態。這個屬性改變時同時引發PlayStateChange事件與StateChange事件。取值範圍爲枚舉型:WMPLib.WMPPlayState,它的成員如下:
  wmppsUndefined = 0;   //未知狀態
  wmppsStopped = 1;    //播放停止
  wmppsPaused = 2;     //播放暫停
  wmppsPlaying = 3;     //正在播放
  wmppsScanForward = 4;   //向前搜索
  wmppsScanReverse = 5;   //向後搜索
  wmppsBuffering = 6;     //正在緩衝
  wmppsWaiting = 7;      //正在等待流開始
  wmppsMediaEnded = 8;    //播放流已結束
  wmppsTransitioning = 9;    //準備新的媒體文件
  wmppsReady = 10;      //播放準備就緒
  wmppsReconnecting = 11;   //嘗試重新連接流媒體數據
  wmppsLast = 12;       //上一次狀態,狀態沒有改變
  在PlayStateChange中寫代碼可以防止播放rmvb等非默認類型的問題(用wmppsReady)。
enableContextMenu:Boolean;    啓用/禁用右鍵菜單
fullScreen:boolean;         是否全屏顯示

//播放器基本控制
Ctlcontrols.play; 播放
Ctlcontrols.pause; 暫停
Ctlcontrols.stop; 停止
Ctlcontrols.currentPosition:double; 當前進度
Ctlcontrols.currentPositionString:string; 當前進度,字符串格式。如“00:23”
Ctlcontrols.fastForward; 快進
Ctlcontrols.fastReverse; 快退
Ctlcontrols.next; 下一曲
Ctlcontrols.previous; 上一曲

[settings] wmp.settings //播放器基本設置
settings.volume:integer; 音量,0-100
settings.autoStart:Boolean; 是否自動播放
settings.mute:Boolean; 是否靜音
settings.playCount:integer; 播放次數
//順序播放
wmp.settings.setMode("shuffle", False)
//隨機播放
wmp.settings.setMode("shuffle", True)
//循環播放
wmp.settings.setMode("loop", True)

[currentMedia] wmp.currentMedia //當前媒體屬性
currentMedia.duration:double; 媒體總長度
currentMedia.durationString:string; 媒體總長度,字符串格式。如“03:24”
currentMedia.getItemInfo(const string); 獲取當前媒體信息"Title"=媒體標題,"Author"=藝術家,"Copyright"=版權信息,"Description"=媒體內容描述, "Duration"=持續時間(秒),"FileSize"=文件大小,"FileType"=文件類型,"sourceURL"=原始地址
currentMedia.setItemInfo(const string); 通過屬性名設置媒體信息
currentMedia.name:string; 同 currentMedia.getItemInfo("Title")

[currentPlaylist] wmp.currentPlaylist //當前播放列表屬性
currentPlaylist.count:integer; 當前播放列表所包含媒體數
currentPlaylist.Item[integer]; 獲取或設置指定項目媒體信息,其子屬性同wmp.currentMedia
axWindowsMediaPlayer1.currentMedia.sourceURL; //獲取正在播放的媒體文件的路徑
axWindowsMediaPlayer1.currentMedia.name;          //獲取正在播放的媒體文件的名稱
axWindowsMediaPlayer1.Ctlcontrols.Play          播放  
axWindowsMediaPlayer1.Ctlcontrols.Stop          停止  
axWindowsMediaPlayer1.Ctlcontrols.Pause          暫停  
axWindowsMediaPlayer1.Ctlcontrols.PlayCount         文件播放次數  
axWindowsMediaPlayer1.Ctlcontrols.AutoRewind       是否循環播放 (無效)
axWindowsMediaPlayer1.Ctlcontrols.Balance          聲道  
axWindowsMediaPlayer1.Ctlcontrols.Volume         音量  
axWindowsMediaPlayer1.Ctlcontrols.Mute          靜音  
axWindowsMediaPlayer1.EnableContextMenu     是否允許在控件上點擊鼠標右鍵時彈出快捷菜單  
axWindowsMediaPlayer1.Ctlcontrols.AnimationAtStart       是否在播放前先播放動畫(無效)
axWindowsMediaPlayer1.Ctlcontrols.ShowControls       是否顯示控件工具欄(無效)
axWindowsMediaPlayer1.Ctlcontrols.ShowAudioControls       是否顯示聲音控制按鈕(無效) 
axWindowsMediaPlayer1.Ctlcontrols.ShowDisplay         是否顯示數據文件的相關信息(無效) 
axWindowsMediaPlayer1.Ctlcontrols.ShowGotoBar        是否顯示Goto欄(無效)
axWindowsMediaPlayer1.Ctlcontrols.ShowPositionControls       是否顯示位置調節按鈕(無效)
axWindowsMediaPlayer1.Ctlcontrols.ShowStatusBar      是否顯示狀態欄(無效)
axWindowsMediaPlayer1.Ctlcontrols.ShowTracker       是否顯示進度條(無效)
axWindowsMediaPlayer1.Ctlcontrols.FastForward        快進  
axWindowsMediaPlayer1.Ctlcontrols.FastReverse        快退  
axWindowsMediaPlayer1.Ctlcontrols.Rate            快進/快退速率  
axWindowsMediaPlayer1.AllowChangeDisplaySize   是否允許自由設置播放圖象大小(無效)
axWindowsMediaPlayer1.DisplaySize       設置播放圖象大小(無效)
1-MpDefaultSize         原始大小  
2-MpHalfSize           原始大小的一半  
3-MpDoubleSize         原始大小的兩倍  
4-MpFullScreen          全屏  
5-MpOneSixteenthScreen      屏幕大小的1/16  
6-MpOneFourthScreen        屏幕大小的1/4  
7-MpOneHalfScreen          屏幕大小的1/2  
axWindowsMediaPlayer1.ClickToPlay    是否允許單擊播放窗口啓動Media Player 

在視頻播放之後,可以通過如下方式讀取源視頻的寬度和高度,然後設置其還原爲原始的大小.
         private void ResizeOriginal()
         {
             int intWidth = axWindowsMediaPlayer1.currentMedia.imageSourceWidth;
             int intHeight = axWindowsMediaPlayer1.currentMedia.imageSourceHeight;
             axWindowsMediaPlayer1.Width = intWidth + 2;
             axWindowsMediaPlayer1.Height = intHeight + 2;
         }

打開媒體文件並播放:

         Dim filePath As String
         With Me.OpenFileDialog1
             .Title = "打開語音文件"
             .CheckPathExists = True
             .CheckFileExists = True
             .Multiselect = False
             .Filter = "mp3文件(*.mp3)|*.mp3|所有文件(*.*)|*.*"
             If .ShowDialog = DialogResult.Cancel Then
                 Exit Sub
             End If
             filePath = .FileName
         End With
         Me.Text = "PC復讀機-文件 " & filePath
         AxWindowsMediaPlayer1.URL = filePath
         Try
             Me.AxWindowsMediaPlayer1.Ctlcontrols.play()
         Catch ex As Exception
             MsgBox("對不起,不能播放此格式語音文件", MsgBoxStyle.OKOnly, "PC復讀機")
             Exit Sub
        End Try
注意:
AxWindowsMediaPlayer1.URL 中URL是表示要播放的文件名,取消了原來的Name屬性.
AxWindowsMediaPlayer1.Ctlcontrols.play()播放,同樣還有Pause,Stop等其他屬性.
AxWindowsMediaPlayer1.settings.balance表示媒體播放的聲道設置,0表示均衡,-1和1表示左右聲道.
AxWindowsMediaPlayer1.currentMedia.duration 表示要播放的文件的時間長度.可用它獲取文件長度.
AxWindowsMediaPlayer1.Ctlcontrols.currentPosition表示正在播放的文件的當前播放位置,可用這個屬性來對媒體文件進行前進後退等設置.如
AxWindowsMediaPlayer1.Ctlcontrols.currentPosition+1 表示前進1個時間單位.
AxWindowsMediaPlayer1.settings.rate播放速率,一般乘以16後再顯示kbps單位.
注意:在上面程序中,如果在後面加上一個:
msgbox(AxWindowsMediaPlayer1.currentMedia.duration.ToString )
則顯示結果很可能爲0,因此,這時候很可能獲取不到文件的播放時間長度,容易出錯。所以在利用的時候可以加一個timer控件:
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
         EndPoint = AxWindowsMediaPlayer1.currentMedia.duration
         If EndPoint = 0 Then Exit Sub '可能因爲媒體文件的打開需要一定時間,這裏等待媒體文件的打開
         msgbox(AxWindowsMediaPlayer1.currentMedia.duration.ToString )
End Sub
此時msgbox便會顯示文件播放長度。
2. Ctlcontrols屬性
Ctlcontrols屬性是AxWindowsMediaPlayer的一個重要屬性, 此控件中有許多常用成員。
(1) 方法play
用於播放多媒體文件,其格式爲:
窗體名.控件名.Ctlcontrols.play()
如: AxWindowsMediaPlayer1.Ctlcontrols.play()  ‘此處缺省窗體名是Me
(2) 方法pause
用於暫停正在播放的多媒體文件,其格式爲:
窗體名.控件名.Ctlcontrols.pause()
如: AxWindowsMediaPlayer1.Ctlcontrols.pause()
(3) 方法stop
用於停止正在播放的多媒體文件,其格式爲:
窗體名.控件名.Ctlcontrols.stop()
如: AxWindowsMediaPlayer1.Ctlcontrols.stop()
(4) 方法fastforward
用於將正在播放的多媒體文件快進,其格式爲:
窗體名.控件名.Ctlcontrols.fastforward()
如: AxWindowsMediaPlayer1.Ctlcontrols.forward()
(5) 方法fastreverse
窗體名.控件名.Ctlcontrols.fastreverse()
如: AxWindowsMediaPlayer1.Ctlcontrols.fastreverse()
6. 屬性CurrentPosition
用於獲取多媒體文件當前的播放進度,其值是數值類型,使用格式爲:
窗體名.控件名.Ctlcontrols.currentPosition
d1 =AxWindowsMediaPlayer1.Ctlcontrols.currentPosition
其中d1 是一個整型變量。
7. 屬性Duration
用於獲取當前多媒體文件的播放的總時間,其值爲數值類型,其使用格式爲:
窗體名.控件名.currentMedia.duration
如:d2 =AxWindowsMediaPlayer1.currentMedia.duration
其中d2是一個整型變量。
對WMP的感嘆
感嘆一
這是我找到的關於WMP的最全的中文資料了。剛纔又查了一下,查到了MSDN有更全的API文檔,終於找到它了。上面的資料基本上夠用了,但是,如果要寫一個更爲精緻的播放器,這些還不夠啊。看MSDN去也。WMP11在MSDN中的位置如下:
win32和COM開發-Griphics And MultiMedia-Audio And Vedio-Windows Media Player 11 SDK
看 了一個晚上的MSDN與資料。發現MSDN上關於WMP SDK的文檔也很不紮實。沒有實例。我要找的答案都不在上面。唯一的收穫是曉得了wpl。wmp有自己的播放列表文件,但是,我查遍msdn,發現sdk 並不提供手動保存播放列表的任何方法。所以,現在的問題是,我們創建了一個IWMPPlayList,但是,這個接口不提供任何保存的方法,結果。 newPlayList(name,path)只提供打開一個已有列表。鬱悶。查了英文資料。老外建議用:StreamWrite/StreamRead 的辦法來讀寫wpl,我也看了。事實上wpl是一個xml文件。我們可以用System.Xml中的API來讀寫。不過,sdk中的這個漏子我始終無法釋 懷。
感嘆二
從WMP8開始就不支持mms/rtsp協議了,所用wmp.URL="mms://xxxx";是不行的了。點此處見詳情,而mms這個協議現在還在廣泛使用。鬱悶。因此,我們不能使用wmp來看網絡電視了。
使用WMP的常見問題:
一、升級wmp後,再拖windows media player控件至窗體出錯的問題(至今沒解決,應當是修改工程序文件,用文本編輯器)
二、 播放rmvb/rm等非官方格式文件要先雙擊文件再點播放按鈕,而不能直接播放的問題,並彈出消息框:Windows Media Player下載文件遇到問題。有關幫助信息請單擊“Web幫助”。消息下面兩個按鈕:關閉、Web幫助。我沒有找到出現這個問題的官方說明。我個人意 見,這是因爲wmp默認只播能播放官方指定的幾種類型的媒體。如果不是,wmp會試圖下載對應的解碼器來播放。而這個下載過程失敗了,所以彈出這個消息 框。wmp好像沒有去判斷這個解碼器是否已經存在。但是,如果你再點播放的話,又能播放,這是什麼原因呢?應當是wmp在這次會試圖搜索本機上的解碼器以 圖播放媒體。怎樣解決這個點兩次鼠標的問題呢?如下:

先設置屬性:wmp.settings.enableErrorDialogs = false;事實上這個屬性默認就是false。不用設置。


private void wmp_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
         //如果已播放完畢就播放下一個文件
         if ((WMPLib.WMPPlayState)e.newState == WMPLib.WMPPlayState.wmppsReady) wmp.Ctlcontrols.play();
}  
唉,我費了九牛二虎之力總算找到了這個辦法解決。

  三、怎樣獲得一個媒體文件中的信息,並且修改媒體的一些信息?

  有辦法:AxWindowsMediaPlayer.newMedia(filename),它會創建一個IWMPMedia的實例。用它的setItemInfo就成了。至於有哪些信息可供設置,可去msdn中查,裏面列舉了所有相關信息。

  四、IWMPPlayList是不是雞肋????????
確實是好大的一塊雞肋!!!!!!!!!!!

  五、播放器控件有幾個組成部分,可有隱藏其中相關部分的方法?

  媒體播放器包括如下元素:
Video Display Panel:視頻顯示面板;
Video Border:視頻邊框;
Closed Captioning Display Panel;字幕顯示面板;
Track Bar;搜索欄;
Control Bar with Audio and Position Controls:帶有聲音和位置控制的控制欄;
Go To Bar:轉到欄;
Display Panel:顯示面板;
Status Bar:狀態欄;

  就是這麼幾個部分,網上有資料說控件提供方法控制它們顯示與否,但是我在sdk中並沒有找到它們。唯一可以粗略控制它們的就是uiMode屬性。它的取值前面有。

  六、控件的網絡設置,如設置代理、緩衝次數、緩衝時間等信息在哪設置?

  AxWindowsMediaPlayer.netWork。它是IWMPNetWork的實例。

  七、像暴風有字幕相關信息的設置,wmp控件有這個功能嗎?

  當然有。就是AxWindowsMediaPlayer.closedCaption。它是IWMPClosedCaption的實例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章