Fix more edge cases on player initialization

This commit is contained in:
ronaldheft
2022-08-19 22:15:06 -04:00
parent a59f3bb957
commit 062a217946
5 changed files with 89 additions and 36 deletions
+4
View File
@@ -58,6 +58,7 @@
E9D5507128AC1EC700C746DD /* DownloadItemPart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507028AC1EC700C746DD /* DownloadItemPart.swift */; };
E9D5507328AC218300C746DD /* DaoExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507228AC218300C746DD /* DaoExtensions.swift */; };
E9D5507528AEF93100C746DD /* PlayerSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507428AEF93100C746DD /* PlayerSettings.swift */; };
E9E985F828B02D9400957F23 /* PlayerProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E985F728B02D9400957F23 /* PlayerProgress.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -116,6 +117,7 @@
E9D5507028AC1EC700C746DD /* DownloadItemPart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadItemPart.swift; sourceTree = "<group>"; };
E9D5507228AC218300C746DD /* DaoExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaoExtensions.swift; sourceTree = "<group>"; };
E9D5507428AEF93100C746DD /* PlayerSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerSettings.swift; sourceTree = "<group>"; };
E9E985F728B02D9400957F23 /* PlayerProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerProgress.swift; sourceTree = "<group>"; };
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -144,6 +146,7 @@
children = (
3A200C1427D64D7E00CBF02E /* AudioPlayer.swift */,
3ABF618E2804325C0070250E /* PlayerHandler.swift */,
E9E985F728B02D9400957F23 /* PlayerProgress.swift */,
);
path = player;
sourceTree = "<group>";
@@ -419,6 +422,7 @@
3AF1970E2806E3CA0096F747 /* AbsAudioPlayer.swift in Sources */,
E9D5506F28AC1E8E00C746DD /* DownloadItem.swift in Sources */,
3AD4FCE928043FD7006DB301 /* ServerConnectionConfig.swift in Sources */,
E9E985F828B02D9400957F23 /* PlayerProgress.swift in Sources */,
E9D5505E28AC1C8500C746DD /* MediaProgress.swift in Sources */,
3A200C1527D64D7E00CBF02E /* AudioPlayer.swift in Sources */,
E9D5507128AC1EC700C746DD /* DownloadItemPart.swift in Sources */,
+4 -4
View File
@@ -29,19 +29,19 @@ public class AbsAudioPlayer: CAPPlugin {
}
@objc func onReady(_ call: CAPPluginCall) {
self.restorePlaybackSession()
Task { await self.restorePlaybackSession() }
}
func restorePlaybackSession() {
func restorePlaybackSession() async {
// We don't need to restore if we have an active session
guard PlayerHandler.getPlaybackSession() == nil else { return }
do {
// Fetch the most recent active session
let activeSession = try Realm().objects(PlaybackSession.self).where({ $0.isActiveSession == true }).last
let activeSession = try await Realm().objects(PlaybackSession.self).where({ $0.isActiveSession == true }).last
if let activeSession = activeSession {
await PlayerProgress.syncLocalFromServer()
try self.startPlaybackSession(activeSession, playWhenReady: false, playbackRate: PlayerSettings.main().playbackRate)
//PlayerHandler.syncServerProgressDuringPause()
}
} catch {
NSLog("Failed to restore playback session")
+2 -28
View File
@@ -297,33 +297,7 @@ 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
session.updatedAt = serverLastUpdate
}
self.seek(amount: session.currentTime)
}
}
}
@objc private static func syncServerProgressDuringPause() {
Task { await PlayerProgress.syncLocalFromServer() }
}
}
@@ -0,0 +1,69 @@
//
// PlayerProgressSync.swift
// App
//
// Created by Ron Heft on 8/19/22.
//
import Foundation
import UIKit
import RealmSwift
class PlayerProgress {
private init() {}
public static func syncLocalFromPlayer() async {
}
public static func syncServerFromLocal() async {
}
public static func syncLocalFromServer() async {
let backgroundToken = await UIApplication.shared.beginBackgroundTask(withName: "ABS:updateLocalSessionFromServerMediaProgress")
await updateLocalSessionFromServerMediaProgress()
await UIApplication.shared.endBackgroundTask(backgroundToken)
}
private static func updateLocalSessionFromActivePlayer() {
}
private static func updateLocalMediaProgressFromLocalSession() {
}
private static func updateServerSessionFromLocalSession() {
}
private static func updateLocalSessionFromServerMediaProgress() async {
NSLog("checkCurrentSessionProgress: Checking if local media progress was updated on server")
guard let session = PlayerHandler.getPlaybackSession() else { return }
// Fetch the current progress
let progress = await ApiClient.getMediaProgress(libraryItemId: session.libraryItemId!, episodeId: session.episodeId)
guard let progress = progress else { return }
// Determine which session is newer
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
// Update the session, if needed
if serverIsNewerThanLocal && currentTimeIsDifferent {
session.update {
session.currentTime = serverCurrentTime
session.updatedAt = serverLastUpdate
}
PlayerHandler.seek(amount: session.currentTime)
}
}
}
+10 -4
View File
@@ -106,6 +106,14 @@ class ApiClient {
}
}
public static func getResource<T: Decodable>(endpoint: String, decodable: T.Type = T.self) async -> T? {
return await withCheckedContinuation { continuation in
getResource(endpoint: endpoint, decodable: decodable) { result in
continuation.resume(returning: result)
}
}
}
public static func getResource<T: Decodable>(endpoint: String, decodable: T.Type = T.self, callback: ((_ param: T?) -> Void)?) {
if (Store.serverConfig == nil) {
NSLog("Server config not set")
@@ -205,12 +213,10 @@ class ApiClient {
}
}
public static func getMediaProgress(libraryItemId: String, episodeId: String?, callback: @escaping (_ progress: MediaProgress?) -> Void) {
public static func getMediaProgress(libraryItemId: String, episodeId: String?) async -> MediaProgress? {
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)
}
return await getResource(endpoint: endpoint, decodable: MediaProgress.self)
}
public static func getLibraryItemWithProgress(libraryItemId:String, episodeId:String?, callback: @escaping (_ param: LibraryItem?) -> Void) {