Avplayer Resuming After Incoming Call

Resuming AVPlayer after phone call

I solved this but creating a shared VideoPlayer class that contained references to all the screen that had animations.

import Foundation
import UIKit
import AVKit

class VideoPlayer: NSObject {

static var shared: VideoPlayer = VideoPlayer()

var avPlayer: AVPlayer!
var avPlayerLayer: AVPlayerLayer!

weak var vcForConnect:ConnectVC?
weak var vcForList:ListVC?

override init() {
super.init()
guard let path = Bundle.main.path(forResource: "animation", ofType:"mp4") else {
print("video not found")
return
}
avPlayer = AVPlayer(url: URL(fileURLWithPath: path))
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer.volume = 0
avPlayer.actionAtItemEnd = .none
loopVideo(videoPlayer: avPlayer)
avPlayer.play()
NotificationCenter.default.addObserver(self, selector: #selector(handleInterruption(notification:)), name: AVAudioSession.interruptionNotification, object: nil)

}

deinit {
avPlayer.pause()
}

@objc func handleInterruption(notification: Notification) {
guard let info = notification.userInfo,
let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
return
}
if type == .began {
// Interruption began, take appropriate actions (save state, update user interface)
self.avPlayer.pause()
} else if type == .ended {
guard let optionsValue =
info[AVAudioSessionInterruptionOptionKey] as? UInt else {
return
}
let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
if options.contains(.shouldResume) {
// Interruption Ended - playback should resume
self.avPlayer.play()
}
}
}

func resumeAllAnimations() {
self.avPlayer.play()
if vcForList?.avPlayer != nil {
vcForList?.avPlayer.play()
}
if vcForConnect?.avPlayer != nil {
vcForConnect?.avPlayer.play()
}
if vcForConnect?.avPlayerBG != nil {
vcForConnect?.avPlayerBG.play()
}
}
...
}

I then resume the animations by calling resumeAllAnimations() in applicationDidBecomeActive(_:) in AppDelegate.swift like so:

func applicationDidBecomeActive(_ application: UIApplication) {
VideoPlayer.shared.resumeAllAnimations()
...
}

Resume AVAudioPlayer after phone call not working

I tried to do the same, although I didn't use any options in the setActive method.

There seem to be a bug in iOS 9.3.1 that doesn't resume playback of the AVAudioPlayer after the phone call ends.

Here is a snippet of what solved it for me: (Sorry for the Objective-C)

- (void)handleInterruption:(NSNotification *) notification{
if (notification.name != AVAudioSessionInterruptionNotification || notification.userInfo == nil) {
return;
}

NSDictionary *info = notification.userInfo;

if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {

if ([[info valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
NSLog(@"InterruptionTypeBegan");
} else {
NSLog(@"InterruptionTypeEnded");

//*The* Workaround - Add a small delay to the avplayer's play call; Without the delay, the playback will *not* be resumed
//
//(I didn't play much with the times, but 0.01 works with my iPhone 6S 9.3.1)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
NSLog(@"playing");
[_player play];
});
}
}
}

I added a small delay to the player's play call, and it worked.

You can find the full Demo project I made here:
https://github.com/liorazi/AVAudioSessionWorkaround

I submitted a radar to Apple, hopefully it'll get fixed on the next release.

How to resume background audio in Swift 2 / AVPlayer?

Finally got it!

Solution: added the mixable option by changing the setCategory line to be:

AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback,
withOptions: .mixWithOthers )


Related Topics



Leave a reply



Submit