Begin handling playback of local media

This commit is contained in:
ronaldheft 2022-07-31 13:33:36 -04:00
parent 76de92fe1f
commit 0b46a9c9b1
5 changed files with 95 additions and 20 deletions

View file

@ -36,30 +36,36 @@ public class AbsAudioPlayer: CAPPlugin {
NSLog("provide library item id") NSLog("provide library item id")
return call.resolve() return call.resolve()
} }
if libraryItemId!.starts(with: "local") {
NSLog("local items are not implemnted")
return call.resolve()
}
initialPlayWhenReady = playWhenReady initialPlayWhenReady = playWhenReady
initialPlaybackRate = playbackRate initialPlaybackRate = playbackRate
PlayerHandler.stopPlayback() PlayerHandler.stopPlayback()
sendPrepareMetadataEvent(itemId: libraryItemId!, playWhenReady: playWhenReady) let isLocalItem = libraryItemId?.starts(with: "local_") ?? false
ApiClient.startPlaybackSession(libraryItemId: libraryItemId!, episodeId: episodeId, forceTranscode: false) { session in if (isLocalItem) {
do { let item = Database.shared.getLocalLibraryItem(localLibraryItem: libraryItemId!)
self.sendPlaybackSession(session: try session.asDictionary()) // TODO: Logic required for podcasts here
call.resolve(try session.asDictionary()) let playbackSession = item?.getPlaybackSession(episode: nil)
} catch(let exception) { PlayerHandler.startPlayback(session: playbackSession!, playWhenReady: playWhenReady, playbackRate: playbackRate)
NSLog("failed to convert session to json")
debugPrint(exception)
call.resolve([:])
}
PlayerHandler.startPlayback(session: session, playWhenReady: playWhenReady, playbackRate: playbackRate)
self.sendMetadata() self.sendMetadata()
call.resolve()
} else { // Playing from the server
sendPrepareMetadataEvent(itemId: libraryItemId!, playWhenReady: playWhenReady)
ApiClient.startPlaybackSession(libraryItemId: libraryItemId!, episodeId: episodeId, forceTranscode: false) { session in
do {
self.sendPlaybackSession(session: try session.asDictionary())
call.resolve(try session.asDictionary())
} catch(let exception) {
NSLog("failed to convert session to json")
debugPrint(exception)
call.resolve([:])
}
PlayerHandler.startPlayback(session: session, playWhenReady: playWhenReady, playbackRate: playbackRate)
self.sendMetadata()
}
} }
} }
@objc func closePlayback(_ call: CAPPluginCall) { @objc func closePlayback(_ call: CAPPluginCall) {

View file

@ -125,7 +125,7 @@ class LocalFile: Object, Encodable {
} }
class LocalMediaProgress: Object, Encodable { class LocalMediaProgress: Object, Encodable {
@Persisted var id: String = UUID().uuidString @Persisted(primaryKey: true) var id: String = UUID().uuidString
@Persisted var localLibraryItemId: String @Persisted var localLibraryItemId: String
@Persisted var localEpisodeId: String? = "" @Persisted var localEpisodeId: String? = ""
@Persisted var duration: Double @Persisted var duration: Double

View file

@ -58,6 +58,53 @@ extension LocalLibraryItem {
self.serverAddress = server.address self.serverAddress = server.address
self.serverUserId = server.userId self.serverUserId = server.userId
} }
func getDuration() -> Double {
var total = 0.0
self.media?.tracks.forEach { track in total += track.duration }
return total
}
func getPlaybackSession(episode: LocalPodcastEpisode?) -> PlaybackSession {
let localEpisodeId = episode?.id
let sessionId = "play_local_\(UUID().uuidString)"
// Get current progress from local media
let mediaProgressId = (localEpisodeId != nil) ? "\(self.id)-\(localEpisodeId!)" : self.id
let mediaProgress = Database.shared.getLocalMediaProgress(localMediaProgressId: mediaProgressId)
// TODO: Clean up add mediaType methods for displayTitle and displayAuthor
let mediaMetadata = self.media?.metadata
let audioTracks = self.media?.tracks
let authorName = mediaMetadata?.authorName
if let episode = episode {
// TODO: Implement podcast
}
let dateNow = Date().timeIntervalSince1970
return PlaybackSession(
id: sessionId,
userId: self.serverUserId,
libraryItemId: self.libraryItemId,
episodeId: episode?.serverEpisodeId,
mediaType: self.mediaType,
chapters: [],
displayTitle: mediaMetadata?.title,
displayAuthor: authorName,
coverPath: nil,
duration: self.getDuration(),
playMethod: 3,
startedAt: dateNow,
updatedAt: 0,
timeListening: 0.0,
audioTracks: [],
currentTime: mediaProgress?.currentTime ?? 0.0,
libraryItem: nil,
serverConnectionConfigId: self.serverConnectionConfigId,
serverAddress: self.serverAddress
)
}
} }
extension LocalMediaType { extension LocalMediaType {

View file

@ -25,8 +25,8 @@ struct PlaybackSession: Decodable, Encodable {
var timeListening: Double var timeListening: Double
var audioTracks: [AudioTrack] var audioTracks: [AudioTrack]
var currentTime: Double var currentTime: Double
var libraryItem: LibraryItem var libraryItem: LibraryItem?
// var localLibraryItem: LocalLibraryItem? //var localLibraryItem: LocalLibraryItem?
var serverConnectionConfigId: String? var serverConnectionConfigId: String?
var serverAddress: String? var serverAddress: String?
} }

View file

@ -229,4 +229,26 @@ class Database {
} }
} }
} }
public func saveLocalMediaProgress(_ mediaProgress: LocalMediaProgress) {
Database.realmQueue.sync {
try! instance.write { instance.add(mediaProgress) }
}
}
// For books this will just be the localLibraryItemId for podcast episodes this will be "{localLibraryItemId}-{episodeId}"
public func getLocalMediaProgress(localMediaProgressId: String) -> LocalMediaProgress? {
Database.realmQueue.sync {
instance.object(ofType: LocalMediaProgress.self, forPrimaryKey: localMediaProgressId)
}
}
public func removeLocalMediaProgress(localMediaProgressId: String) {
Database.realmQueue.sync {
try! instance.write {
let progress = instance.object(ofType: LocalMediaProgress.self, forPrimaryKey: localMediaProgressId)
instance.delete(progress!)
}
}
}
} }