我开发了UWP应用程序,它可以在后台或手机锁定时播放音频文件。该应用程序工作正常,一切似乎完美5-10分钟。之后,当我运行应用程序时,我无法播放音频文件,并且我在主题中附加了异常。但是,如果我重新启动应用程序,一切正常。我已经按照以下步骤添加了以下代码和项目来完成任务。
添加了以下代码以发送背景信息
BackgroundMediaPlayer.MessageReceivedFromBackground + = BackgroundMediaPlayer_MessageReceivedFromBackground;
添加了Windows组件运行时(Windows Universal),其代码如下
在Package.appxmanifest中添加了入口点和后台任务
public sealed class AudioPlayer : IBackgroundTask {
private BackgroundTaskDeferral deferral;
private SystemMediaTransportControls systemmediatransportcontrol;
public void Run(IBackgroundTaskInstance taskInstance) {
systemmediatransportcontrol = BackgroundMediaPlayer.Current.SystemMediaTransportControls;
systemmediatransportcontrol.ButtonPressed += systemmediatransportcontrol_ButtonPressed;
systemmediatransportcontrol.PropertyChanged += systemmediatransportcontrol_PropertyChanged;
systemmediatransportcontrol.IsEnabled = true;
systemmediatransportcontrol.IsPauseEnabled = true;
systemmediatransportcontrol.IsPlayEnabled = true;
systemmediatransportcontrol.IsNextEnabled = true;
systemmediatransportcontrol.IsPreviousEnabled = true;
BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged;
BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground;
deferral = taskInstance.GetDeferral();
taskInstance.Canceled += TaskInstance_Canceled;
taskInstance.Task.Completed += Taskcompleted;
}
void Taskcompleted(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) {
deferral.Complete();
}
private void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) {
try {
systemmediatransportcontrol.ButtonPressed -= systemmediatransportcontrol_ButtonPressed;
systemmediatransportcontrol.PropertyChanged -= systemmediatransportcontrol_PropertyChanged;
BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline
}
catch (Exception) {
}
deferral.Complete();
}
void Current_CurrentStateChanged(MediaPlayer sender, object args) {
MediaPlayer player = sender;
switch (player.CurrentState) {
case MediaPlayerState.Playing:
systemmediatransportcontrol.PlaybackStatus = MediaPlaybackStatus.Playing;
break;
case MediaPlayerState.Paused:
systemmediatransportcontrol.PlaybackStatus = MediaPlaybackStatus.Stopped;
break;
}
}
void systemmediatransportcontrol_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args) {
try {
switch (args.Button) {
case SystemMediaTransportControlsButton.Play:
playTrack();
break;
case SystemMediaTransportControlsButton.Pause:
stopBeforePlaying();
break;
case SystemMediaTransportControlsButton.Next:
stopBeforePlaying();
nextTrack();
break;
case SystemMediaTransportControlsButton.Previous:
stopBeforePlaying();
previousTrack();
break;
}
}
catch (Exception) {
//Debug.WriteLine(ex.Message);
}
}
void stopBeforePlaying() {
MediaPlayer player = BackgroundMediaPlayer.Current;
if (player != null)
player.Pause();
}
void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e) {
object foregroundMessageType;
if (e.Data.TryGetValue(ApplicationSettingsConstants.ChapterStatus, out foregroundMessageType)) {
//do something here
}
}
void UpdateUVCOnNewTrack() {
//update buttons here
}
async void playTrack() {
MediaPlayer player = BackgroundMediaPlayer.Current;
try {
if (...) {
//load track
player.Play();
}
else {
player.Pause();
MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
}
}
catch (System.IO.DirectoryNotFoundException) {
player.Pause();
MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
}
catch (System.IO.FileNotFoundException) {
player.Pause();
MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
}
finally {
UpdateUVCOnNewTrack();
}
}
void nextTrack() {
//load next track
}
void previousTrack() {
//load previous here
}
}
为什么我收到上述错误?
注意:我已按照Microsoft Sample Background Audio for Windows Phone 8.1 Sample启用了背景音频播放器。
谢谢!
答案 0 :(得分:1)
某些情况可能会导致BackgroundAudio.Reference中的此异常Windows-universal-samples/Samples/BackgroundAudio/cs/BackgroundAudio/Scenario1.xaml.cs,函数ResetAfterLostBackground()
的注释
后台任务确实存在,但它已经消失了。将前景恢复到初始状态。不幸的是,一旦后台任务丢失,任何在BackgroundMediaPlayer.Current上注销事物的尝试都将因RPC错误而失败。
添加此函数,并在捕获错误的地方调用它。
const int RPC_S_SERVER_UNAVAILABLE = -2147023174; // 0x800706BA
private void ResetAfterLostBackground()
{
BackgroundMediaPlayer.Shutdown();
try
{
BackgroundMediaPlayer.MessageReceivedFromBackground += BackgroundMediaPlayer_MessageReceivedFromBackground;
}
catch (Exception ex)
{
if (ex.HResult == RPC_S_SERVER_UNAVAILABLE)
{
throw new Exception("Failed to get a MediaPlayer instance.");
}
else
{
throw;
}
}
}