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 = {
|
let startPlaying = {
|
||||||
#if !os(macOS)
|
#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
|
#endif
|
||||||
|
|
||||||
self.setRate(self.model.currentRate)
|
self.setRate(self.model.currentRate)
|
||||||
|
@ -248,13 +248,6 @@ final class MPVBackend: PlayerBackend {
|
|||||||
#if !os(macOS)
|
#if !os(macOS)
|
||||||
do {
|
do {
|
||||||
try AVAudioSession.sharedInstance().setActive(true)
|
try AVAudioSession.sharedInstance().setActive(true)
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
|
||||||
self,
|
|
||||||
selector: #selector(self.handleAudioSessionInterruption(_:)),
|
|
||||||
name: AVAudioSession.interruptionNotification,
|
|
||||||
object: nil
|
|
||||||
)
|
|
||||||
} catch {
|
} catch {
|
||||||
self.logger.error("Error setting up audio session: \(error)")
|
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)")
|
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()
|
static var shared = PlayerModel()
|
||||||
|
|
||||||
let logger = Logger(label: "stream.yattee.app")
|
let logger = Logger(label: "stream.yattee.player.model")
|
||||||
|
|
||||||
var playerItem: AVPlayerItem?
|
var playerItem: AVPlayerItem?
|
||||||
|
|
||||||
@ -204,6 +204,14 @@ final class PlayerModel: ObservableObject {
|
|||||||
#if !os(macOS)
|
#if !os(macOS)
|
||||||
mpvBackend.controller = mpvController
|
mpvBackend.controller = mpvController
|
||||||
mpvBackend.client = mpvController.client
|
mpvBackend.client = mpvController.client
|
||||||
|
|
||||||
|
// Register for audio session interruption notifications
|
||||||
|
NotificationCenter.default.addObserver(
|
||||||
|
self,
|
||||||
|
selector: #selector(handleAudioSessionInterruption(_:)),
|
||||||
|
name: AVAudioSession.interruptionNotification,
|
||||||
|
object: nil
|
||||||
|
)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
playbackMode = Defaults[.playbackMode]
|
playbackMode = Defaults[.playbackMode]
|
||||||
@ -220,6 +228,10 @@ final class PlayerModel: ObservableObject {
|
|||||||
currentRate = playerRate
|
currentRate = playerRate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
NotificationCenter.default.removeObserver(self, name: AVAudioSession.interruptionNotification, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
func show() {
|
func show() {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
if presentingPlayer {
|
if presentingPlayer {
|
||||||
@ -1231,6 +1243,42 @@ final class PlayerModel: ObservableObject {
|
|||||||
return nil
|
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)
|
#if os(macOS)
|
||||||
private func assignKeyPressMonitor() {
|
private func assignKeyPressMonitor() {
|
||||||
keyPressMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { keyEvent -> NSEvent? in
|
keyPressMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { keyEvent -> NSEvent? in
|
||||||
|
Loading…
Reference in New Issue
Block a user