Windows Phone播放视频流

  • 前言

     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

    MediaStreamSource是用于将视频流直接送入MediaElement的媒体管道中的类,也能够做为用于MediaElement不支持的视频格式的中转站。经过MediaElement的SetSource方法指定,SetSource方法也能够用来播放本地的视频流。为了完成网络视频流的转换等处理,一般咱们自定义一个继承MediaStreamSoure的类,再实现一些必要的方法。好比,OpenMediaAsyncGetSampleAsyncSeekAsync等。下面咱们就来看看一个简单的自定义类实现的步骤。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。格式转换是一个在视频播放中很复杂的问题,这里就不进行介绍了,有须要的同窗能够留言讨论或者自行研究。事件

相关文章
相关标签/搜索