MediaElement是Windows Phone中播放本地或者網絡視頻文件和音樂文件的經常使用控件,支持的格式能夠從這裏看。經過Play,Pause,Stop,Position方法或屬性能夠方便的控制文件的播放暫停或快進。MediaElement包含6種狀態,分別是buffering、opening、playing、closed、stopped、pause。能夠經過註冊MediaElement的CurrentStateChanged事件來獲取CurrentState來對UI作出不一樣的響應。須要注意的是,MediaElement在某些特定狀態下對於API的調用不會當即反應。好比,當MediaElement的狀態在buffering的時候,若是調用Play事件,MediaElement要等到緩衝結束後才能執行Play操做。在這種場景下就須要咱們針對特定的CurrentState作出UI上的交互來填補緩衝時間帶來的程序無響應問題。下面就來給出一個XAML的例子。網絡
<MediaElement x:Name="media" Source="xbox.wmv" CurrentStateChanged="media_state_changed" Width="300" Height="300"/>
Source是控制播放文件路徑的屬性,上面給出一個播放本地文件的例子,也能夠指定網絡上的文件路徑。當更改或設置Source的值後,MediaElement的狀態會進入opening,若是設置Source爲null,則會進入closed狀態。今天咱們重點要說的是,如何使用MediaElement播放網絡的視頻流,即直播的場景。ide
MediaStreamSource是用於將視頻流直接送入MediaElement的媒體管道中的類,也能夠做爲用於MediaElement不支持的視頻格式的中轉站。經過MediaElement的SetSource方法指定,SetSource方法也能夠用來播放本地的視頻流。爲了完成網絡視頻流的轉換等處理,一般咱們自定義一個繼承MediaStreamSoure的類,再實現一些必要的方法。好比,OpenMediaAsync、GetSampleAsync、SeekAsync等。下面咱們就來看看一個簡單的自定義類實現的步驟。spa
protected override void OpenMediaAsync() { //描述媒體示例 _mediaSampleAttributes[MediaSampleAttributeKeys.FrameHeight] = _height.ToString(); _mediaSampleAttributes[MediaSampleAttributeKeys.FrameWidth] = _width.ToString(); //描述媒體流 _mediaStreamAttributes[MediaStreamAttributeKeys.Height] = _height.ToString(); _mediaStreamAttributes[MediaStreamAttributeKeys.Width] = _width.ToString(); _mediaStreamAttributes[MediaStreamAttributeKeys.CodecPrivateData] =""; _mediaStreamAttributes[MediaStreamAttributeKeys.VideoFourCC] ="H264"; //詳盡描述媒體流 _mediaStreamDescriptions.Add(new MediaStreamDescription(MediaStreamType.Video, _mediaStreamAttributes)); //描述媒體源 Dictionary<MediaSourceAttributesKeys, string> mediaSourceAttributes =new Dictionary<MediaSourceAttributesKeys, string>(); mediaSourceAttributes[MediaSourceAttributesKeys.CanSeek] ="false"; mediaSourceAttributes[MediaSourceAttributesKeys.Duration] = _duration.ToString(CultureInfo.InvariantCulture); ReportOpenMediaCompleted(mediaSourceAttributes, _mediaStreamDescriptions); }
當MediaElement的Source被指定後將進入opening狀體,這時將調用OpenMediaAsync方法。這個方法用來描述將要播放的視頻流的流體,高寬,格式,長短等信息。VideoFourCC屬性表明要播放的流的視頻格式,它是由一個四個字符的字符串指定,好比:"H264","MP43","YV12"等。經過調用ReportOpenMediaCompleted方法告知MediaElement視頻流已經打開能夠繼續進行下面的操做。code
protected override void GetSampleAsync(MediaStreamType mediaStreamType) { var msd =new MediaStreamDescription(MediaStreamType.Video, _mediaStreamAttributes); //詳盡描述媒體示例 var mediaSample =new MediaStreamSample( msd, _mediaStream, _offect, _count, _timeStamp, _mediaSampleAttributes); ReportGetSampleCompleted(mediaSample); }
在MediaStreamSource打開以後,將調用GetSampleAsync方法。上面的代碼經過ReportGetSampleCompleted方法將組織好的視頻流裝入到媒體管道中。若是這個時候視頻流因爲網絡緣由或者須要轉碼等操做尚未準備好,那麼咱們能夠調用ReportGetSampleProgress方法來通知MediaElement緩衝的進度,這時MediaElement將進入到buffering狀態,若是當前的CurrrentState是Playing,那麼視頻播放將暫停播放進入到buffering狀態。GetSampleAsync方法會被調用屢次,直到再次受到來自ReportGetSampleCompleted的視頻流才繼續播放。視頻
protected override void SeekAsync(long seekToTime) { ReportSeekCompleted(seekToTime); }
在播放網絡媒體視頻流的過程當中經常須要進度條的功能。若是將MediaSourceAttributesKeys.CanSeek的屬性值設成false,那麼SeekAsync的參數seekToTime將是0。若是你要實現進度條的功能,那麼必需要確保seekToTime的值在視頻的duration以內。若是改觸發了進度,那麼咱們就須要從新組織視頻流,直到從新調用ReportGetSampleCompleted方法,MediaElement纔會繼續播放。blog
當視頻播放接受後咱們須要插入一個空的MediaStreamSample來告知MediaElement視頻播放結束,這時CurrentState將進入到closed狀態。繼承
以上咱們簡單的介紹了在Windows Phone中播放視頻流的方法,播放音頻流的方法也是如此,須要修改MediaStreamType屬性的值。流的來源能夠經過Socket或者Http。格式轉換是一個在視頻播放中很複雜的問題,這裏就不進行介紹了,有須要的同窗能夠留言討論或者自行研究。事件