MSDN帮助:http://msdn.microsoft.com/en-us/library/hh394039(v=VS.92).aspx
一)简介
使用手机上的Zune播放器播放MP3时,会发现一个情况:选择歌曲播放,然后退出Zune,这时音乐仍然是在播放的,同时在锁定屏幕上会显示出当前播放的歌曲信息(歌曲名称和演唱者),还有一组音乐播放的快捷操作按钮,快捷操作按钮包括三个:前一首、播放/暂停、后一首。在锁屏或其他情况下(XNA游戏估计不行)按下音量调节键会呼叫显示出这组快捷操作按钮。停止播放后,大约一个小时超时期限(在此期间内没有按下音量调节键或打开Zune播放器来播放歌曲)后,此效果则会自动消失,也就是说,按下音量调节按键时只会出现正常的手机音量调节界面,音乐播放的歌曲信息和快捷操作按钮都不会显示。这就是后台播放音乐。
后台播放音乐的两种类型:
使用播放列表来播放(普通的音乐播放),播放媒体流(收听FM电台或网络广播)。
似乎这个后台播放动作是绑定到一个应用程序中的,所以需要创建两个工程来实现后台播放音乐。一个是普通的应用程序,一个则是后台播放代理。大致的过程是:应用程序启动时,OS会在后台创建一个BackgrounfAudioPlayer的实例,应用程序访问BackgrounfAudioPlayer的实例,调用其属性和方法来发出指令,后台播放代理则响应前端发出的指令动作。
二)前端界面
一个普通的Silverlight类型的WP应用程序,主要是对BackgrounfAudioPlayer的实例的访问和调用。
1)BackgroundAudioPlayer的属性:
BufferingProgress double的类型 缓冲进度
PlayerState 枚举PlayState的类型 播放状态
Position TimeSpan的类型 播放位置
Track AudioTrack的类型 音轨信息(歌曲的名称、演唱者、风格、持续时长、所属专辑、专辑封面图片)
Volume double的类型 音量大小,取值范围0-1,0表示无声,1表示最大音量,默认值是0.85。
2)BackgroundAudioPlayer的方法:
Play 播放
Pause 暂停
Stop 停止
Rewind 重放
SkipNext 播放后一首
SkipPrevious 播放前一首
FastForward 快进播放
Close 关闭
3)BackgroundAudioPlayer的事件:
PlayStateChanged 播放状态变化时触发,用于界面控件的显示更新。
4)工程的WMAppManifest.xml文件中的变化:
<Tasks>
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
<ExtendedTask Name="BackgroundTask">
<BackgroundServiceAgent Specifier="AudioPlayerAgent" Name="MyAudioPlaybackAgent" Source="MyAudioPlaybackAgent" Type="MyAudioPlaybackAgent.AudioPlayer" />
</ExtendedTask>
</Tasks>
我把ExtendedTask标签去除掉,运行程序后界面正常显示,但是点击按钮没有任何反应。
5)在App.xaml.cs的构造函数中加入下面代码(主要是用于调试):
if (System.Diagnostics.Debugger.IsAttached)
// Close the background audio player in case it
// was running from a previous debugging session.
BackgroundAudioPlayer.Instance.Close();
特别注意:BackgrounfAudioPlayer只能播放隔离区中的歌曲文件,或者是网络上的歌曲文件。(媒体库中的文件不行吗?纳闷)
三)后台播放代理(播放列表)
从AudioPlayerAgent继承实现一个后台播放代理的类,主要任务是创建维护播放列表,同时响应BackgrounfAudioPlayer的指令(应该是提供给BackgrounfAudioPlayer作回调之用)。
1)覆盖重写基类的事件:
OnPlayStateChanged,除了Error状态之外的其他状态发生变化时的事件处理,主要是调用BackgroundAudioPlayer的方法属性进行初始化处理,最后完成时调用NotifyComplete。特别注意的是:TrackEnded是在代理第一次运行时会触发;TrackReady是在音轨加载完成时会触发。
OnUserAction,主要是调用BackgroundAudioPlayer的方法响应用户的操作,最后完成时调用NotifyComplete。
OnError,响应处理异常错误,某些错误情况下是不会执行该事件的,主要是用于日志记录吧。
OnCancel,用户取消(暂时不知怎么取消)事件,代理有5秒钟的时间来处理取消事件,似乎作用不明显。
2)最佳实践
生命周期:由BackgrounfAudioPlayer实例在需要时创建,出来完成之后(内部调用NotifyComplete或Abort后)自动销毁。
处理用户动作:SkipNext、SkipPrevious、Play这些动作都是依次排队进行处理的,不论动作会持续多长时间;每个动作调用最长允许时间为30秒;Play和Pause动作可能会需要较长的时间(数秒甚至数分钟),这需要特别注意。
不能同时使用BackgrounfAudioPlayer和MediaElement,即一个播放、另一个暂停;切换到MediaElement之前,必须要先调用BackgrounfAudioPlayer的Close方法。
内存和运行时限制:在处理响应动作时,AudioPlayerAgent类型的代理必须在30秒内调用NotifyComplete或Abort来结束响应处理,AudioStreamingAgent类型的代理则不限制,且运行时间也不限制,两种类型的代理共享同一个进程空间和最大为15MB的内存空间。