Background audio playback does not work

I've searched everything, but can't get this to work consistently. I want to play audio when a remote push notification arrives, when the app is in the background or on the locked screen and the call is muted.

The steps I followed:

1) Set the required background modes to "Application plays audio" in info.plist.

2) In the application: didFinishLaunchingWithOptions: a) set the audio connection category to Play b) activate the audio session. c) make the application receive remote control events and become the first responder

- (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) In applicationDidEnterBackground: a) start background job b) receive remote events

- (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) When the remote notification arrives, play the audio file

- (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];
}

      

It works sometimes, but not always. Any ideas how to make this work consistently?

+3


source to share


1 answer


I think you cannot start playing background audio while in the background even starting from applicationDidEnterBackground too late. Perhaps you can work without sound or audio pause. You can use a queue player to accomplish this by looping the sound without sound and aiming for the start when it ends, and then insert the sound you want to play after it into the queue.



0


source







All Articles