advplyr.audiobookshelf-app/ios/App/Shared/player/PlayerHandler.swift

174 lines
5.7 KiB
Swift
Raw Normal View History

2022-04-11 16:29:19 +02:00
//
// PlayerHandler.swift
// App
//
// Created by Rasmus Krämer on 11.04.22.
//
import Foundation
2022-08-16 12:32:22 -04:00
import RealmSwift
2022-04-11 16:29:19 +02:00
class PlayerHandler {
private static var player: AudioPlayer?
2022-04-15 12:21:46 +02:00
2022-08-11 18:49:04 -05:00
public static var sleepTimerChapterStopTime: Int? = nil
2022-08-16 20:45:29 -04:00
2022-08-16 12:32:22 -04:00
public static func startPlayback(sessionId: String, playWhenReady: Bool, playbackRate: Float) {
guard let session = Database.shared.getPlaybackSession(id: sessionId) else { return }
2022-08-16 20:45:29 -04:00
// Clean up the existing player
2022-04-12 14:28:47 +02:00
if player != nil {
player?.destroy()
player = nil
}
2022-08-22 17:04:48 -04:00
// Cleanup and sync old sessions
2022-08-16 20:45:29 -04:00
cleanupOldSessions(currentSessionId: sessionId)
2022-08-22 17:04:48 -04:00
Task { await PlayerProgress.shared.syncToServer() }
2022-08-16 20:45:29 -04:00
// Set now playing info
2022-05-03 12:55:13 +02:00
NowPlayingInfo.shared.setSessionMetadata(metadata: NowPlayingMetadata(id: session.id, itemId: session.libraryItemId!, artworkUrl: session.coverPath, title: session.displayTitle ?? "Unknown title", author: session.displayAuthor, series: nil))
2022-04-15 12:21:46 +02:00
2022-08-16 20:45:29 -04:00
// Create the audio player
2022-08-16 12:32:22 -04:00
player = AudioPlayer(sessionId: sessionId, playWhenReady: playWhenReady, playbackRate: playbackRate)
2022-04-11 16:29:19 +02:00
}
2022-04-14 14:39:09 +02:00
public static func stopPlayback() {
2022-08-13 12:41:20 -04:00
// Pause playback first, so we can sync our current progress
player?.pause()
2022-04-14 14:39:09 +02:00
2022-08-13 12:41:20 -04:00
player?.destroy()
player = nil
2022-08-16 20:45:29 -04:00
cleanupOldSessions(currentSessionId: nil)
2022-05-03 12:55:13 +02:00
NowPlayingInfo.shared.reset()
2022-04-14 14:39:09 +02:00
}
2022-08-22 17:04:48 -04:00
public static var paused: Bool {
get {
guard let player = player else { return true }
return player.rate == 0.0
}
set(paused) {
if paused {
self.player?.pause()
} else {
self.player?.play()
}
}
}
public static var remainingSleepTime: Int? {
get {
guard let player = player else { return nil }
// Consider paused as playing at 1x
let rate = Double(player.rate > 0 ? player.rate : 1)
if let sleepTimerChapterStopTime = sleepTimerChapterStopTime {
let timeUntilChapterEnd = Double(sleepTimerChapterStopTime) - player.getCurrentTime()
let timeUntilChapterEndScaled = timeUntilChapterEnd / rate
return Int(timeUntilChapterEndScaled.rounded())
} else if let stopAt = player.getSleepStopAt() {
let timeUntilSleep = stopAt - player.getCurrentTime()
let timeUntilSleepScaled = timeUntilSleep / rate
return Int(timeUntilSleepScaled.rounded())
} else {
return nil
}
}
}
2022-04-14 14:39:09 +02:00
public static func getCurrentTime() -> Double? {
self.player?.getCurrentTime()
}
2022-04-14 14:39:09 +02:00
public static func setPlaybackSpeed(speed: Float) {
self.player?.setPlaybackRate(speed)
}
2022-08-22 17:04:48 -04:00
public static func setSleepTime(secondsUntilSleep: Double) {
guard let player = player else { return }
let stopAt = secondsUntilSleep + player.getCurrentTime()
player.setSleepTime(stopAt: stopAt, scaleBasedOnSpeed: true)
}
public static func setChapterSleepTime(stopAt: Double) {
guard let player = player else { return }
self.sleepTimerChapterStopTime = Int(stopAt)
player.setSleepTime(stopAt: stopAt, scaleBasedOnSpeed: false)
}
public static func increaseSleepTime(increaseSeconds: Double) {
self.player?.increaseSleepTime(extraTimeInSeconds: increaseSeconds)
}
public static func decreaseSleepTime(decreaseSeconds: Double) {
self.player?.decreaseSleepTime(removeTimeInSeconds: decreaseSeconds)
}
public static func cancelSleepTime() {
self.player?.removeSleepTimer()
}
public static func getPlayMethod() -> Int? {
self.player?.getPlayMethod()
}
public static func getPlaybackSession() -> PlaybackSession? {
2022-08-16 12:32:22 -04:00
guard let player = player else { return nil }
2022-08-21 12:36:29 -04:00
guard player.isInitialized() else { return nil }
2022-08-22 17:04:48 -04:00
return Database.shared.getPlaybackSession(id: player.getPlaybackSessionId())
}
2022-04-14 14:39:09 +02:00
public static func seekForward(amount: Double) {
2022-08-21 12:36:29 -04:00
guard let player = player else { return }
2022-04-14 14:39:09 +02:00
2022-05-03 12:55:13 +02:00
let destinationTime = player.getCurrentTime() + amount
player.seek(destinationTime, from: "handler")
2022-04-14 14:39:09 +02:00
}
2022-04-14 14:39:09 +02:00
public static func seekBackward(amount: Double) {
2022-08-21 12:36:29 -04:00
guard let player = player else { return }
2022-04-14 14:39:09 +02:00
2022-05-03 12:55:13 +02:00
let destinationTime = player.getCurrentTime() - amount
player.seek(destinationTime, from: "handler")
2022-04-14 14:39:09 +02:00
}
2022-04-14 14:39:09 +02:00
public static func seek(amount: Double) {
player?.seek(amount, from: "handler")
2022-04-14 14:39:09 +02:00
}
2022-08-16 21:14:33 -04:00
public static func getMetdata() -> [String: Any]? {
guard let player = player else { return nil }
guard player.isInitialized() else { return nil }
2022-04-14 14:39:09 +02:00
return [
2022-08-16 21:14:33 -04:00
"duration": player.getDuration(),
"currentTime": player.getCurrentTime(),
2022-05-03 14:32:46 +02:00
"playerState": !paused,
2022-08-16 21:14:33 -04:00
"currentRate": player.rate,
2022-04-14 14:39:09 +02:00
]
}
2022-04-15 12:21:46 +02:00
2022-08-22 17:04:48 -04:00
// MARK: - Helper logic
private static func cleanupOldSessions(currentSessionId: String?) {
let realm = try! Realm()
let oldSessions = realm.objects(PlaybackSession.self) .where({ $0.isActiveSession == true })
try! realm.write {
for s in oldSessions {
if s.id != currentSessionId {
s.isActiveSession = false
2022-08-11 18:49:04 -05:00
}
}
2022-04-15 12:21:46 +02:00
}
}
2022-08-19 23:00:40 -04:00
@objc public static func syncServerProgressDuringPause() {
Task { await PlayerProgress.shared.syncFromServer() }
}
2022-04-11 16:29:19 +02:00
}