mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-04 18:15:01 +02:00
Add an AudioPlayerRateManager implementation for iOS 16+.
This commit is contained in:
parent
edb25f5bcd
commit
f8a9033738
2 changed files with 100 additions and 1 deletions
|
@ -62,7 +62,12 @@ class AudioPlayer: NSObject {
|
|||
self.audioPlayer.automaticallyWaitsToMinimizeStalling = true
|
||||
self.sessionId = sessionId
|
||||
self.status = .uninitialized
|
||||
self.rateManager = LegacyAudioPlayerRateManager(audioPlayer: self.audioPlayer, defaultRate: playbackRate)
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
self.rateManager = DefaultedAudioPlayerRateManager(audioPlayer: self.audioPlayer, defaultRate: playbackRate)
|
||||
} else {
|
||||
self.rateManager = LegacyAudioPlayerRateManager(audioPlayer: self.audioPlayer, defaultRate: playbackRate)
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
|
|
94
ios/App/Shared/player/DefaultedAudioPlayerRateManager.swift
Normal file
94
ios/App/Shared/player/DefaultedAudioPlayerRateManager.swift
Normal file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// DefaultedAudioPlayerRateManager.swift
|
||||
// Audiobookshelf
|
||||
//
|
||||
// Created by Marke Hallowell on 4/14/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import AVFoundation
|
||||
|
||||
@available(iOS 16.0, *)
|
||||
class DefaultedAudioPlayerRateManager: NSObject, AudioPlayerRateManager {
|
||||
internal let logger = AppLogger(category: "DefaultedAudioPlayerRateManager")
|
||||
|
||||
internal var audioPlayer: AVPlayer
|
||||
|
||||
// MARK: - AudioPlayerRateManager
|
||||
public private(set) var defaultRate: Float
|
||||
public private(set) var rate: Float
|
||||
public var rateChangedCompletion: () -> Void
|
||||
public var defaultRateChangedCompletion: () -> Void
|
||||
|
||||
required init(audioPlayer: AVPlayer, defaultRate: Float) {
|
||||
self.audioPlayer = audioPlayer
|
||||
self.rateChangedCompletion = {}
|
||||
self.defaultRateChangedCompletion = {}
|
||||
self.rate = self.audioPlayer.rate
|
||||
self.defaultRate = defaultRate
|
||||
self.audioPlayer.defaultRate = defaultRate
|
||||
|
||||
super.init()
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleObservedRateChange), name: AVPlayer.rateDidChangeNotification, object: self.audioPlayer)
|
||||
}
|
||||
|
||||
public func setPlaybackRate(_ rate: Float) {
|
||||
self.handlePlaybackRateChange(rate, observed: false)
|
||||
}
|
||||
|
||||
// No-op (player automatically resumes at last-known defaultRate)
|
||||
public func handlePlayEvent() { }
|
||||
|
||||
// MARK: - Destructor
|
||||
public func destroy() {
|
||||
NotificationCenter.default.removeObserver(self, name: AVPlayer.rateDidChangeNotification, object: self.audioPlayer)
|
||||
}
|
||||
|
||||
// MARK: - Internal
|
||||
internal func handlePlaybackRateChange(_ rate: Float, observed: Bool = false) {
|
||||
let playbackSpeedChanged = rate > 0.0 && rate != self.defaultRate
|
||||
|
||||
if playbackSpeedChanged {
|
||||
self.defaultRate = rate
|
||||
self.audioPlayer.defaultRate = rate
|
||||
self.defaultRateChangedCompletion()
|
||||
|
||||
// Check to see if we also need to make a temporary rate change to player
|
||||
if self.audioPlayer.rate > 0.0 {
|
||||
if self.audioPlayer.rate != rate {
|
||||
self.rate = rate
|
||||
self.audioPlayer.rate = rate
|
||||
self.rateChangedCompletion()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.rate = rate
|
||||
self.rateChangedCompletion()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - iOS rate change notification handler
|
||||
@objc internal func handleObservedRateChange(notification: Notification) {
|
||||
// TODO: Consider handling cases individually (e.g. overall session impact?)
|
||||
/*
|
||||
guard let reason = notification.userInfo?[AVPlayer.rateDidChangeReasonKey] as? AVPlayer.RateDidChangeReason else {
|
||||
return
|
||||
}
|
||||
|
||||
switch reason {
|
||||
case .appBackgrounded:
|
||||
// App transitioned to the background.
|
||||
case .audioSessionInterrupted:
|
||||
// The system interrupts the app's audio session.
|
||||
case .setRateCalled:
|
||||
// The app set the player's rate.
|
||||
case .setRateFailed:
|
||||
// An attempt to change the player's rate failed.
|
||||
default:
|
||||
break
|
||||
}
|
||||
*/
|
||||
self.handlePlaybackRateChange(self.audioPlayer.rate, observed: true)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue