mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-07-12 15:04:43 +02:00
Begin handling playback of local media
This commit is contained in:
parent
76de92fe1f
commit
0b46a9c9b1
5 changed files with 95 additions and 20 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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?
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue