mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-29 06:37:16 +02:00
Fix more edge cases on player initialization
This commit is contained in:
@@ -58,6 +58,7 @@
|
|||||||
E9D5507128AC1EC700C746DD /* DownloadItemPart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507028AC1EC700C746DD /* DownloadItemPart.swift */; };
|
E9D5507128AC1EC700C746DD /* DownloadItemPart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507028AC1EC700C746DD /* DownloadItemPart.swift */; };
|
||||||
E9D5507328AC218300C746DD /* DaoExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507228AC218300C746DD /* DaoExtensions.swift */; };
|
E9D5507328AC218300C746DD /* DaoExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507228AC218300C746DD /* DaoExtensions.swift */; };
|
||||||
E9D5507528AEF93100C746DD /* PlayerSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5507428AEF93100C746DD /* PlayerSettings.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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@@ -116,6 +117,7 @@
|
|||||||
E9D5507028AC1EC700C746DD /* DownloadItemPart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadItemPart.swift; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@@ -144,6 +146,7 @@
|
|||||||
children = (
|
children = (
|
||||||
3A200C1427D64D7E00CBF02E /* AudioPlayer.swift */,
|
3A200C1427D64D7E00CBF02E /* AudioPlayer.swift */,
|
||||||
3ABF618E2804325C0070250E /* PlayerHandler.swift */,
|
3ABF618E2804325C0070250E /* PlayerHandler.swift */,
|
||||||
|
E9E985F728B02D9400957F23 /* PlayerProgress.swift */,
|
||||||
);
|
);
|
||||||
path = player;
|
path = player;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -419,6 +422,7 @@
|
|||||||
3AF1970E2806E3CA0096F747 /* AbsAudioPlayer.swift in Sources */,
|
3AF1970E2806E3CA0096F747 /* AbsAudioPlayer.swift in Sources */,
|
||||||
E9D5506F28AC1E8E00C746DD /* DownloadItem.swift in Sources */,
|
E9D5506F28AC1E8E00C746DD /* DownloadItem.swift in Sources */,
|
||||||
3AD4FCE928043FD7006DB301 /* ServerConnectionConfig.swift in Sources */,
|
3AD4FCE928043FD7006DB301 /* ServerConnectionConfig.swift in Sources */,
|
||||||
|
E9E985F828B02D9400957F23 /* PlayerProgress.swift in Sources */,
|
||||||
E9D5505E28AC1C8500C746DD /* MediaProgress.swift in Sources */,
|
E9D5505E28AC1C8500C746DD /* MediaProgress.swift in Sources */,
|
||||||
3A200C1527D64D7E00CBF02E /* AudioPlayer.swift in Sources */,
|
3A200C1527D64D7E00CBF02E /* AudioPlayer.swift in Sources */,
|
||||||
E9D5507128AC1EC700C746DD /* DownloadItemPart.swift in Sources */,
|
E9D5507128AC1EC700C746DD /* DownloadItemPart.swift in Sources */,
|
||||||
|
|||||||
@@ -29,19 +29,19 @@ public class AbsAudioPlayer: CAPPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc func onReady(_ call: CAPPluginCall) {
|
@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
|
// We don't need to restore if we have an active session
|
||||||
guard PlayerHandler.getPlaybackSession() == nil else { return }
|
guard PlayerHandler.getPlaybackSession() == nil else { return }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Fetch the most recent active session
|
// 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 {
|
if let activeSession = activeSession {
|
||||||
|
await PlayerProgress.syncLocalFromServer()
|
||||||
try self.startPlaybackSession(activeSession, playWhenReady: false, playbackRate: PlayerSettings.main().playbackRate)
|
try self.startPlaybackSession(activeSession, playWhenReady: false, playbackRate: PlayerSettings.main().playbackRate)
|
||||||
//PlayerHandler.syncServerProgressDuringPause()
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
NSLog("Failed to restore playback session")
|
NSLog("Failed to restore playback session")
|
||||||
|
|||||||
@@ -297,33 +297,7 @@ class PlayerHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public static func syncServerProgressDuringPause() {
|
@objc private static func syncServerProgressDuringPause() {
|
||||||
guard Connectivity.isConnectedToInternet else { return }
|
Task { await PlayerProgress.syncLocalFromServer() }
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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)?) {
|
public static func getResource<T: Decodable>(endpoint: String, decodable: T.Type = T.self, callback: ((_ param: T?) -> Void)?) {
|
||||||
if (Store.serverConfig == nil) {
|
if (Store.serverConfig == nil) {
|
||||||
NSLog("Server config not set")
|
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")")
|
NSLog("getMediaProgress \(libraryItemId) \(episodeId ?? "NIL")")
|
||||||
let endpoint = episodeId?.isEmpty ?? true ? "api/me/progress/\(libraryItemId)" : "api/me/progress/\(libraryItemId)/\(episodeId ?? "")"
|
let endpoint = episodeId?.isEmpty ?? true ? "api/me/progress/\(libraryItemId)" : "api/me/progress/\(libraryItemId)/\(episodeId ?? "")"
|
||||||
getResource(endpoint: endpoint, decodable: MediaProgress.self) { obj in
|
return await getResource(endpoint: endpoint, decodable: MediaProgress.self)
|
||||||
callback(obj)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func getLibraryItemWithProgress(libraryItemId:String, episodeId:String?, callback: @escaping (_ param: LibraryItem?) -> Void) {
|
public static func getLibraryItemWithProgress(libraryItemId:String, episodeId:String?, callback: @escaping (_ param: LibraryItem?) -> Void) {
|
||||||
|
|||||||
Reference in New Issue
Block a user