在后台应用程序不起作用时播放音频

Posted

技术标签:

【中文标题】在后台应用程序不起作用时播放音频【英文标题】:Play audio while app in background not working 【发布时间】:2015-06-17 19:37:40 【问题描述】:

我已经搜索了所有内容,但无法使其始终如一地工作。我想在应用处于后台或锁定屏幕且铃声关闭时收到远程推送通知时播放音频。

我遵循的步骤:

1) 将所需的背景模式设置为“应用程序播放音频”到 info.plist。

2) 在应用程序中:didFinishLaunchingWithOptions: a) 将音频会话类别设置为播放 b) 激活音频会话。 c) 使应用接收远程控制事件并成为第一响应者

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

  // https://developer.apple.com/library/ios/qa/qa1668/_index.html
  // For playback to continue when the screen locks, or when the Ring/Silent switch is set to silent, use the AVAudioSessionCategoryPlayback
  BOOL result = [audioSession setCategory:AVAudioSessionCategoryPlayback error:&sessionError]; // TODO AVAudioSessionCategorySoloAmbient

  if (!result && sessionError) 
    NSLog(@"AppDelegate error setting session category. error %@", sessionError);
  
  else 
    NSLog(@"AppDelegate setting session category is successful");
  

  result = [audioSession setActive:YES error:&sessionError];

  if (!result && sessionError) 
    NSLog(@"AppDelegate error activating audio session. error %@", sessionError);
  
  else 
    NSLog(@"AppDelegate setting session active is successful");
  

  [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  [self becomeFirstResponder];

3) 在 applicationDidEnterBackground 中: a) 开始后台任务 b) 接收远程控制事件

- (void)applicationDidEnterBackground:(UIApplication *)application 
  NSLog(@"AppDelegate applicationDidEnterBackground: called");

  NSLog(@"AppDelegate applicationDidEnterBackground: is calling beginBackgroundTaskWithExpirationHandler:");
  [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];

  NSLog(@"AppDelegate applicationDidEnterBackground: is calling beginReceivingRemoteControlEvents");
  [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

4) 当远程通知进来时,播放音频文件

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler 

  _currentItem = [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"Audio" withExtension:@"wav"]];
  _audioPlayer = [AVPlayer playerWithPlayerItem:_currentItem];

  [_currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
  [_audioPlayer addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

  NSLog(@"playAudio: calling [_audioPlayer play] on audioPlayer %@", _audioPlayer);
  [_audioPlayer play];

它有时会起作用,但并非总是如此。任何想法如何使这项工作始终如一?

【问题讨论】:

而不是在application:didFinishLaunchingWithOptions: 中设置音频会话和applicationDidEnterBackground 中的remoteEvent 侦听器尝试仅在didReceiveRemoteNotification 中设置它们。可能会发生会话被其他应用程序覆盖。 @Aanabidden 谢谢,我试过了,但它不会播放。我也只是在 didReceiveRemoteNotification 中设置了 audioSession 并将 beginReceivingRemoteControlEvents 和 beginBackgroundTaskWithExpirationHandler 留在了 didEnterBackground 中,它有时但并非总是有效。我无所适从。还有什么想法吗? 【参考方案1】:

我认为你不能在后台开始播放背景音频,即使从applicationDidEnterBackground 开始也为时已晚。您可以做的一个工作是播放无声音频或暂停音频。您可以使用队列播放器来实现此目的,方法是循环无声音频并在其结束时寻找开头,然后将您想要播放的音频排入队列。

【讨论】:

以上是关于在后台应用程序不起作用时播放音频的主要内容,如果未能解决你的问题,请参考以下文章

Windows 8.1 背景音频播放器在应用程序的其他页面中不起作用

音频遥控器不起作用

当我的应用程序运行时,硬件音量按钮不起作用

为啥我的停止按钮在这个 javascript 音频播放器上不起作用?

当应用程序进入后台时开始播放音频文件

Xml 音频列表播放器在移动设备上不起作用,并且自动播放不起作用