diff --git a/AmperfyKit/AmperfyKit.swift b/AmperfyKit/AmperfyKit.swift index d0220a03..66e791fc 100644 --- a/AmperfyKit/AmperfyKit.swift +++ b/AmperfyKit/AmperfyKit.swift @@ -70,10 +70,10 @@ public class AmperKit { public lazy var notificationHandler: EventNotificationHandler = { return EventNotificationHandler() }() - private var audioSessionHandler: AudioSessionHandler? public private(set) var scrobbleSyncer: ScrobbleSyncer? public lazy var player: PlayerFacade = { - let backendAudioPlayer = BackendAudioPlayer(mediaPlayer: AVPlayer(), eventLogger: eventLogger, backendApi: backendApi, networkMonitor: networkMonitor, playableDownloader: playableDownloadManager, cacheProxy: storage.main.library, userStatistics: userStatistics) + let audioSessionHandler = AudioSessionHandler() + let backendAudioPlayer = BackendAudioPlayer(mediaPlayer: AVPlayer(), audioSessionHandler: audioSessionHandler, eventLogger: eventLogger, backendApi: backendApi, networkMonitor: networkMonitor, playableDownloader: playableDownloadManager, cacheProxy: storage.main.library, userStatistics: userStatistics) networkMonitor.connectionTypeChangedCB = { isWiFiConnected in backendAudioPlayer.streamingMaxBitrates = StreamingMaxBitrates( wifi: self.storage.settings.streamingMaxBitrateWifiPreference, @@ -82,6 +82,8 @@ public class AmperKit { let playerData = storage.main.library.getPlayerData() let queueHandler = PlayQueueHandler(playerData: playerData) let curPlayer = AudioPlayer(coreData: playerData, queueHandler: queueHandler, backendAudioPlayer: backendAudioPlayer, userStatistics: userStatistics) + audioSessionHandler.musicPlayer = curPlayer + audioSessionHandler.configureObserverForAudioSessionInterruption() let playerDownloadPreparationHandler = PlayerDownloadPreparationHandler(playerStatus: playerData, queueHandler: queueHandler, playableDownloadManager: playableDownloadManager) curPlayer.addNotifier(notifier: playerDownloadPreparationHandler) @@ -91,9 +93,6 @@ public class AmperKit { let facadeImpl = PlayerFacadeImpl(playerStatus: playerData, queueHandler: queueHandler, musicPlayer: curPlayer, library: storage.main.library, playableDownloadManager: playableDownloadManager, backendAudioPlayer: backendAudioPlayer, userStatistics: userStatistics) facadeImpl.isOfflineMode = storage.settings.isOfflineMode - audioSessionHandler = AudioSessionHandler(musicPlayer: curPlayer) - audioSessionHandler?.configureObserverForAudioSessionInterruption(audioSession: AVAudioSession.sharedInstance()) - audioSessionHandler?.configureBackgroundPlayback(audioSession: AVAudioSession.sharedInstance()) let nowPlayingInfoCenterHandler = NowPlayingInfoCenterHandler(musicPlayer: curPlayer, backendAudioPlayer: backendAudioPlayer, nowPlayingInfoCenter: MPNowPlayingInfoCenter.default(), storage: storage) curPlayer.addNotifier(notifier: nowPlayingInfoCenterHandler) let remoteCommandCenterHandler = RemoteCommandCenterHandler(musicPlayer: facadeImpl, backendAudioPlayer: backendAudioPlayer, librarySyncer: librarySyncer, eventLogger: eventLogger, remoteCommandCenter: MPRemoteCommandCenter.shared()) diff --git a/AmperfyKit/Player/AudioSessionHandler.swift b/AmperfyKit/Player/AudioSessionHandler.swift index d8ced24e..d8d5d656 100644 --- a/AmperfyKit/Player/AudioSessionHandler.swift +++ b/AmperfyKit/Player/AudioSessionHandler.swift @@ -25,14 +25,10 @@ import os.log class AudioSessionHandler { - private let musicPlayer: AudioPlayer - - init(musicPlayer: AudioPlayer) { - self.musicPlayer = musicPlayer - } + var musicPlayer: AudioPlayer? - func configureObserverForAudioSessionInterruption(audioSession: AVAudioSession) { - NotificationCenter.default.addObserver(self, selector: #selector(handleAudioSessionInterruption), name: AVAudioSession.interruptionNotification, object: audioSession) + func configureObserverForAudioSessionInterruption() { + NotificationCenter.default.addObserver(self, selector: #selector(handleAudioSessionInterruption), name: AVAudioSession.interruptionNotification, object: AVAudioSession.sharedInstance()) } @objc private func handleAudioSessionInterruption(notification: NSNotification) { @@ -47,7 +43,7 @@ class AudioSessionHandler { // Audio has stopped, already inactive // Change state of UI, etc., to reflect non-playing state os_log(.info, "Audio interruption began") - musicPlayer.pause() + musicPlayer?.pause() case AVAudioSession.InterruptionType.ended: // Make session active // Update user interface @@ -58,17 +54,17 @@ class AudioSessionHandler { if interruptionOption == AVAudioSession.InterruptionOptions.shouldResume { // Here you should continue playback os_log(.info, "Audio interruption ended -> Resume playing") - musicPlayer.play() + musicPlayer?.play() } } default: break } } - func configureBackgroundPlayback(audioSession: AVAudioSession) { + func configureBackgroundPlayback() { do { - try audioSession.setCategory(AVAudioSession.Category.playback) - try audioSession.setActive(true) + try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback) + try AVAudioSession.sharedInstance().setActive(true) } catch { os_log(.error, "Error Player: %s", error.localizedDescription) } diff --git a/AmperfyKit/Player/BackendAudioPlayer.swift b/AmperfyKit/Player/BackendAudioPlayer.swift index 39e254d2..0d93dcd5 100644 --- a/AmperfyKit/Player/BackendAudioPlayer.swift +++ b/AmperfyKit/Player/BackendAudioPlayer.swift @@ -51,7 +51,8 @@ class BackendAudioPlayer { private let networkMonitor: NetworkMonitorFacade private let updateElapsedTimeInterval = CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC)) private let fileManager = CacheFileManager.shared - + private var audioSessionHandler: AudioSessionHandler + private var userDefinedPlaybackRate: PlaybackRate = .one public var isOfflineMode: Bool = false @@ -96,8 +97,9 @@ class BackendAudioPlayer { return player.currentItem != nil } - init(mediaPlayer: AVPlayer, eventLogger: EventLogger, backendApi: BackendApi, networkMonitor: NetworkMonitorFacade, playableDownloader: DownloadManageable, cacheProxy: PlayableFileCachable, userStatistics: UserStatistics) { + init(mediaPlayer: AVPlayer, audioSessionHandler: AudioSessionHandler, eventLogger: EventLogger, backendApi: BackendApi, networkMonitor: NetworkMonitorFacade, playableDownloader: DownloadManageable, cacheProxy: PlayableFileCachable, userStatistics: UserStatistics) { self.player = mediaPlayer + self.audioSessionHandler = audioSessionHandler self.backendApi = backendApi self.networkMonitor = networkMonitor self.eventLogger = eventLogger @@ -214,6 +216,7 @@ class BackendAudioPlayer { private func insert(playable: AbstractPlayable, withUrl url: URL, streamingMaxBitrate: StreamingMaxBitratePreference = .noLimit) { player.pause() + audioSessionHandler.configureBackgroundPlayback() player.replaceCurrentItem(with: nil) var item: AVPlayerItem? if let mimeType = playable.iOsCompatibleContentType {