From af835f2c435ca13813f220f1d71d084a78a68295 Mon Sep 17 00:00:00 2001 From: ronaldheft Date: Thu, 18 Aug 2022 19:01:10 -0400 Subject: [PATCH] Persist playback settings --- ios/App/App.xcodeproj/project.pbxproj | 4 +++ ios/App/App/plugins/AbsAudioPlayer.swift | 14 ++++++---- ios/App/Shared/models/PlayerSettings.swift | 30 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 ios/App/Shared/models/PlayerSettings.swift diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index c395188b..1a0f41f2 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -57,6 +57,7 @@ E9D5506F28AC1E8E00C746DD /* DownloadItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9D5506E28AC1E8E00C746DD /* DownloadItem.swift */; }; 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 */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -114,6 +115,7 @@ E9D5506E28AC1E8E00C746DD /* DownloadItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadItem.swift; sourceTree = ""; }; E9D5507028AC1EC700C746DD /* DownloadItemPart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadItemPart.swift; sourceTree = ""; }; E9D5507228AC218300C746DD /* DaoExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaoExtensions.swift; sourceTree = ""; }; + E9D5507428AEF93100C746DD /* PlayerSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerSettings.swift; sourceTree = ""; }; 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 = ""; }; /* End PBXFileReference section */ @@ -180,6 +182,7 @@ E9D5505F28AC1CA900C746DD /* PlaybackMetadata.swift */, E9D5506128AC1CC900C746DD /* PlayerState.swift */, 4DF74911287105C600AC7814 /* DeviceSettings.swift */, + E9D5507428AEF93100C746DD /* PlayerSettings.swift */, E9D5506328AC1D3F00C746DD /* server */, E9D5506428AC1D5800C746DD /* local */, E9D5506D28AC1E7400C746DD /* download */, @@ -436,6 +439,7 @@ 4DF74912287105C600AC7814 /* DeviceSettings.swift in Sources */, E9D5504A28AC1AA600C746DD /* Metadata.swift in Sources */, 3AF197102806E3DC0096F747 /* AbsAudioPlayer.m in Sources */, + E9D5507528AEF93100C746DD /* PlayerSettings.swift in Sources */, E9D5505028AC1B3E00C746DD /* Author.swift in Sources */, 3AF1970C2806E2590096F747 /* ApiClient.swift in Sources */, 4D66B954282EE87C008272D4 /* AbsDownloader.swift in Sources */, diff --git a/ios/App/App/plugins/AbsAudioPlayer.swift b/ios/App/App/plugins/AbsAudioPlayer.swift index be324984..814f39a6 100644 --- a/ios/App/App/plugins/AbsAudioPlayer.swift +++ b/ios/App/App/plugins/AbsAudioPlayer.swift @@ -12,7 +12,6 @@ import RealmSwift @objc(AbsAudioPlayer) public class AbsAudioPlayer: CAPPlugin { private var initialPlayWhenReady = false - private var initialPlaybackRate:Float = 1 override public func load() { NotificationCenter.default.addObserver(self, selector: #selector(sendMetadata), name: NSNotification.Name(PlayerEvents.update.rawValue), object: nil) @@ -39,7 +38,7 @@ public class AbsAudioPlayer: CAPPlugin { // Fetch the most recent active session let activeSession = try Realm().objects(PlaybackSession.self).where({ $0.isActiveSession == true }).last if let activeSession = activeSession { - try self.startPlaybackSession(activeSession, playWhenReady: false) + try self.startPlaybackSession(activeSession, playWhenReady: false, playbackRate: PlayerSettings.main().playbackRate) PlayerHandler.syncServerProgressDuringPause() } } catch { @@ -48,7 +47,7 @@ public class AbsAudioPlayer: CAPPlugin { } } - @objc func startPlaybackSession(_ session: PlaybackSession, playWhenReady: Bool, playbackRate: Float = 1.0) throws { + @objc func startPlaybackSession(_ session: PlaybackSession, playWhenReady: Bool, playbackRate: Float) throws { guard let libraryItemId = session.libraryItemId else { throw PlayerError.libraryItemIdNotSpecified } self.sendPrepareMetadataEvent(itemId: libraryItemId, playWhenReady: playWhenReady) @@ -117,7 +116,12 @@ public class AbsAudioPlayer: CAPPlugin { ]) } @objc func setPlaybackSpeed(_ call: CAPPluginCall) { - PlayerHandler.setPlaybackSpeed(speed: call.getFloat("value", 1.0)) + let playbackRate = call.getFloat("value", 1.0) + let settings = PlayerSettings.main() + settings.update { + settings.playbackRate = playbackRate + } + PlayerHandler.setPlaybackSpeed(speed: settings.playbackRate) call.resolve() } @@ -235,7 +239,7 @@ public class AbsAudioPlayer: CAPPlugin { // If direct playing then fallback to transcode ApiClient.startPlaybackSession(libraryItemId: libraryItemId, episodeId: episodeId, forceTranscode: true) { session in session.save() - PlayerHandler.startPlayback(sessionId: session.id, playWhenReady: self.initialPlayWhenReady, playbackRate: self.initialPlaybackRate) + PlayerHandler.startPlayback(sessionId: session.id, playWhenReady: self.initialPlayWhenReady, playbackRate: PlayerSettings.main().playbackRate) do { self.sendPlaybackSession(session: try session.asDictionary()) diff --git a/ios/App/Shared/models/PlayerSettings.swift b/ios/App/Shared/models/PlayerSettings.swift new file mode 100644 index 00000000..0a8b3788 --- /dev/null +++ b/ios/App/Shared/models/PlayerSettings.swift @@ -0,0 +1,30 @@ +// +// PlayerSettings.swift +// App +// +// Created by Ron Heft on 8/18/22. +// + +import Foundation +import RealmSwift + +class PlayerSettings: Object { + // The webapp has a persisted setting for playback speed, but it's not always available to the native code + // Lets track it natively as well, so we never have a situation where the UI and native player are out of sync + @Persisted var playbackRate: Float = 1.0 + + // Singleton pattern for Realm objects + static func main() -> PlayerSettings { + let realm = try! Realm() + + if let settings = realm.objects(PlayerSettings.self).last { + return settings + } + + let settings = PlayerSettings() + try! realm.write { + realm.add(settings) + } + return settings + } +}