mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-27 04:54:11 +02:00
94 lines
3.2 KiB
Swift
94 lines
3.2 KiB
Swift
//
|
|
// 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)
|
|
}
|
|
}
|