I am playing video using AVPlayer
, it stops iPhone's music which is on going in background. Please help me to resolve
let item1 = AVPlayerItem.init(URL: NSURL(string:path))
player = AVPlayer(playerItem: item1)
layer?.player = player;
player?.play()
My movies are for animations; they have no sound. To let other sound continue playing, in Swift:
// None of our movies should interrupt system music playback.
_ = try? AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: .default, options: .mixWithOthers)
Thanks to Marcus Adams for the original answer.
Use a category for the AVAudioSession that allows mixing, such as AVAudioSessionCategoryPlayback
and add AVAudioSessionCategoryOptionMixWithOthers
.
From the docs:
AVAudioSessionCategoryOptionMixWithOthers
Mixes audio from this session with audio from other active sessions.
Valid only if the session category is
AVAudioSessionCategoryPlayAndRecord or AVAudioSessionCategoryPlayback.
(Implicit if the session category is AVAudioSessionCategoryAmbient.)
If you activate your session while using this option, your app’s audio
will not interrupt audio from other apps (such as the Music app). If
not using this option (or a category that is implicitly mixable),
activating your session will interrupt other nonmixable sessions.
Available in iOS 6.0 and later.
In swift 4.2 Please try this one.
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, options: .mixWithOthers)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
According to Apple
https://developer.apple.com/documentation/avfoundation/media_assets_playback_and_editing/creating_a_basic_video_player_ios_and_tvos/playing_audio_from_a_video_asset_in_the_background
If you want to continue playing audio, you disconnect the AVPlayer instance from the presentation when entering the background and reconnect it when returning to the foreground.
func applicationDidEnterBackground(_ application: UIApplication) {
// Disconnect the AVPlayer from the presentation when entering background
// If presenting video with AVPlayerViewController
playerViewController.player = nil
// If presenting video with AVPlayerLayer
playerLayer.player = nil
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Reconnect the AVPlayer to the presentation when returning to foreground
// If presenting video with AVPlayerViewController
playerViewController.player = player
// If presenting video with AVPlayerLayer
playerLayer.player = player
}
Eg for your ViewController using AVPlayer
Step : 1
Enable Background mode In Capabilities for Audio, AirPlay, and Pictures in pictures
Step : 2
AppDelegate.swift
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)
print("Playback OK")
try AVAudioSession.sharedInstance().setActive(true)
print("Session is Active")
} catch {
print(error)
}
Step : 3
YourViewcontroller.swift
override func viewDidLoad() {
super.viewDidLoad()
addPlayerNotifications()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
removePlayerNotifations()
}
func addPlayerNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(applicationWillEnterForeground), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
}
func removePlayerNotifations() {
NotificationCenter.default.removeObserver(self, name:NSNotification.Name.UIApplicationWillEnterForeground, object: nil)
NotificationCenter.default.removeObserver(self, name:NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
}
//App enter in forground.
@objc func applicationWillEnterForeground(_ notification: Notification) {
yourPlayerLayer.player = yourplayer
}
//App enter in forground.
@objc func applicationDidEnterBackground(_ notification: Notification) {
yourPlayerLayer.player = nil
}