mirror of
https://github.com/yattee/yattee.git
synced 2024-11-09 15:58:20 +00:00
make audio ducking and interruption more robust
Signed-off-by: Toni Förster <toni.foerster@gmail.com> fix audio ducking and bluetooth play/pause Signed-off-by: Toni Förster <toni.foerster@gmail.com>
This commit is contained in:
parent
2d7a101ce0
commit
e8fcee23ef
@ -364,7 +364,11 @@ final class AVPlayerBackend: PlayerBackend {
|
||||
|
||||
let startPlaying = {
|
||||
#if !os(macOS)
|
||||
try? AVAudioSession.sharedInstance().setActive(true)
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(true)
|
||||
} catch {
|
||||
self.logger.error("Error setting up audio session: \(error)")
|
||||
}
|
||||
#endif
|
||||
|
||||
self.setRate(self.model.currentRate)
|
||||
|
@ -248,13 +248,6 @@ final class MPVBackend: PlayerBackend {
|
||||
#if !os(macOS)
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(true)
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(self.handleAudioSessionInterruption(_:)),
|
||||
name: AVAudioSession.interruptionNotification,
|
||||
object: nil
|
||||
)
|
||||
} catch {
|
||||
self.logger.error("Error setting up audio session: \(error)")
|
||||
}
|
||||
@ -649,33 +642,4 @@ final class MPVBackend: PlayerBackend {
|
||||
logger.info("MPV backend received unhandled property: \(name)")
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(macOS)
|
||||
@objc func handleAudioSessionInterruption(_ notification: Notification) {
|
||||
logger.info("Audio session interruption received.")
|
||||
|
||||
guard let info = notification.userInfo,
|
||||
let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt
|
||||
else {
|
||||
logger.info("AVAudioSessionInterruptionTypeKey is missing or not a UInt in userInfo.")
|
||||
return
|
||||
}
|
||||
|
||||
let type = AVAudioSession.InterruptionType(rawValue: typeValue)
|
||||
|
||||
logger.info("Interruption type received: \(String(describing: type))")
|
||||
|
||||
switch type {
|
||||
case .began:
|
||||
pause()
|
||||
logger.info("Audio session interrupted.")
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self, name: AVAudioSession.interruptionNotification, object: nil)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
static var shared = PlayerModel()
|
||||
|
||||
let logger = Logger(label: "stream.yattee.app")
|
||||
let logger = Logger(label: "stream.yattee.player.model")
|
||||
|
||||
var playerItem: AVPlayerItem?
|
||||
|
||||
@ -204,6 +204,14 @@ final class PlayerModel: ObservableObject {
|
||||
#if !os(macOS)
|
||||
mpvBackend.controller = mpvController
|
||||
mpvBackend.client = mpvController.client
|
||||
|
||||
// Register for audio session interruption notifications
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(handleAudioSessionInterruption(_:)),
|
||||
name: AVAudioSession.interruptionNotification,
|
||||
object: nil
|
||||
)
|
||||
#endif
|
||||
|
||||
playbackMode = Defaults[.playbackMode]
|
||||
@ -220,6 +228,10 @@ final class PlayerModel: ObservableObject {
|
||||
currentRate = playerRate
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self, name: AVAudioSession.interruptionNotification, object: nil)
|
||||
}
|
||||
|
||||
func show() {
|
||||
#if os(macOS)
|
||||
if presentingPlayer {
|
||||
@ -1231,6 +1243,42 @@ final class PlayerModel: ObservableObject {
|
||||
return nil
|
||||
}
|
||||
|
||||
#if !os(macOS)
|
||||
@objc func handleAudioSessionInterruption(_ notification: Notification) {
|
||||
logger.info("Audio session interruption received.")
|
||||
logger.info("Notification received: \(notification)")
|
||||
|
||||
guard let info = notification.userInfo,
|
||||
let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
|
||||
let type = AVAudioSession.InterruptionType(rawValue: typeValue)
|
||||
else {
|
||||
logger.info("AVAudioSessionInterruptionTypeKey is missing or not a UInt in userInfo.")
|
||||
return
|
||||
}
|
||||
|
||||
logger.info("Interruption type received: \(type)")
|
||||
|
||||
switch type {
|
||||
case .began:
|
||||
logger.info("Audio session interrupted.")
|
||||
// We need to call pause() to set all variables correctly, and play()
|
||||
// directly afterwards, because the .began interrupt is sent after audio
|
||||
// ducking ended and playback would pause. Audio ducking usually happens
|
||||
// when using headphones.
|
||||
pause()
|
||||
play()
|
||||
case .ended:
|
||||
logger.info("Audio session interruption ended.")
|
||||
// We need to call pause() to set all variables correctly.
|
||||
// Otherwise, playback does not resume when the interruption ends.
|
||||
pause()
|
||||
play()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if os(macOS)
|
||||
private func assignKeyPressMonitor() {
|
||||
keyPressMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { keyEvent -> NSEvent? in
|
||||
|
Loading…
Reference in New Issue
Block a user