Sync player session with server media progress

This commit is contained in:
ronaldheft 2022-08-18 17:08:41 -04:00
parent 519969eee0
commit 5fd3f3c080
3 changed files with 51 additions and 0 deletions

View file

@ -40,6 +40,7 @@ public class AbsAudioPlayer: CAPPlugin {
let activeSession = try Realm().objects(PlaybackSession.self).where({ $0.isActiveSession == true }).last
if let activeSession = activeSession {
try self.startPlaybackSession(activeSession, playWhenReady: false)
PlayerHandler.syncServerProgressDuringPause()
}
} catch {
NSLog("Failed to restore playback session")

View file

@ -11,6 +11,7 @@ import RealmSwift
class PlayerHandler {
private static var player: AudioPlayer?
private static var timer: Timer?
private static var pausedTimer: Timer?
private static var lastSyncTime: Double = 0.0
public static var sleepTimerChapterStopTime: Int? = nil
@ -48,6 +49,7 @@ class PlayerHandler {
self.player?.pause()
} else {
self.player?.play()
self.pausedTimer?.invalidate()
}
}
}
@ -56,6 +58,7 @@ class PlayerHandler {
DispatchQueue.runOnMainQueue {
NSLog("Starting the tick timer")
timer?.invalidate()
pausedTimer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
self.tick()
}
@ -65,9 +68,16 @@ class PlayerHandler {
public static func stopTickTimer() {
NSLog("Stopping the tick timer")
timer?.invalidate()
pausedTimer?.invalidate()
timer = nil
}
private static func startPausedTimer() {
guard self.paused else { return }
self.pausedTimer?.invalidate()
self.pausedTimer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(syncServerProgressDuringPause), userInfo: nil, repeats: true)
}
private static func cleanupOldSessions(currentSessionId: String?) {
let realm = try! Realm()
let oldSessions = realm.objects(PlaybackSession.self) .where({ $0.isActiveSession == true })
@ -99,6 +109,7 @@ class PlayerHandler {
player = AudioPlayer(sessionId: sessionId, playWhenReady: playWhenReady, playbackRate: playbackRate)
startTickTimer()
startPausedTimer()
}
public static func stopPlayback() {
@ -204,6 +215,8 @@ class PlayerHandler {
guard player.isInitialized() else { return }
guard let session = getPlaybackSession() else { return }
NSLog("Syncing player progress")
// Get current time
let playerCurrentTime = player.getCurrentTime()
@ -283,4 +296,33 @@ class PlayerHandler {
}
}
}
@objc public static func syncServerProgressDuringPause() {
guard Connectivity.isConnectedToInternet else { return }
DispatchQueue.global(qos: .utility).async {
NSLog("checkCurrentSessionProgress: Checking if local media progress was updated on server")
guard let session = getPlaybackSession() else { return }
let sessionRef = ThreadSafeReference(to: session)
ApiClient.getMediaProgress(libraryItemId: session.libraryItemId!, episodeId: session.episodeId) { progress in
guard let session = try! Realm().resolve(sessionRef) else { return }
guard let progress = progress else { return }
let serverLastUpdate = progress.lastUpdate
guard let localLastUpdate = session.updatedAt else { return }
let serverCurrentTime = progress.currentTime
let localCurrentTime = session.currentTime
let serverIsNewerThanLocal = serverLastUpdate > localLastUpdate
let currentTimeIsDifferent = serverCurrentTime != localCurrentTime
if serverIsNewerThanLocal && currentTimeIsDifferent {
session.update {
session.currentTime = serverCurrentTime
}
self.seek(amount: session.currentTime)
}
}
}
}
}

View file

@ -205,6 +205,14 @@ class ApiClient {
}
}
public static func getMediaProgress(libraryItemId: String, episodeId: String?, callback: @escaping (_ progress: MediaProgress?) -> Void) {
NSLog("getMediaProgress \(libraryItemId) \(episodeId ?? "NIL")")
let endpoint = episodeId?.isEmpty ?? true ? "api/me/progress/\(libraryItemId)" : "api/me/progress/\(libraryItemId)/\(episodeId ?? "")"
getResource(endpoint: endpoint, decodable: MediaProgress.self) { obj in
callback(obj)
}
}
public static func getLibraryItemWithProgress(libraryItemId:String, episodeId:String?, callback: @escaping (_ param: LibraryItem?) -> Void) {
var endpoint = "api/items/\(libraryItemId)?expanded=1&include=progress"
if episodeId != nil {