First pass at attempting to save library items

This commit is contained in:
ronaldheft 2022-07-09 18:37:32 -04:00
parent e620f53705
commit 175e642081
3 changed files with 64 additions and 31 deletions

View file

@ -33,25 +33,24 @@ public class AbsDownloader: CAPPlugin {
private func startLibraryItemDownload(item: LibraryItem) { private func startLibraryItemDownload(item: LibraryItem) {
let length = item.media.tracks?.count ?? 0 let length = item.media.tracks?.count ?? 0
if length > 0 { if length > 0 {
let localLibraryItem = LocalLibraryItem(item: item, localUrl: documentsDirectory, server: Store.serverConfig!) let files = item.media.tracks!.enumerated().map {
position, track -> LocalFile in startLibraryItemTrackDownload(item: item, position: position, track: track)
item.media.tracks?.enumerated().forEach { position, track in
startLibraryItemTrackDownload(item: item, position: position, track: track)
} }
let localLibraryItem = LocalLibraryItem(item: item, localUrl: documentsDirectory, server: Store.serverConfig!, files: files)
Database.shared.saveLocalLibraryItem(localLibraryItem: localLibraryItem) Database.shared.saveLocalLibraryItem(localLibraryItem: localLibraryItem)
} else { } else {
NSLog("No audio tracks for the supplied library item") NSLog("No audio tracks for the supplied library item")
} }
} }
private func startLibraryItemTrackDownload(item: LibraryItem, position: Int, track: AudioTrack) { private func startLibraryItemTrackDownload(item: LibraryItem, position: Int, track: AudioTrack) -> LocalFile {
NSLog("TRACK \(track.contentUrl!)") NSLog("TRACK \(track.contentUrl!)")
// If we don't name metadata, then we can't proceed // If we don't name metadata, then we can't proceed
guard let filename = track.metadata?.filename else { guard let filename = track.metadata?.filename else {
NSLog("No metadata for track, unable to download") NSLog("No metadata for track, unable to download")
return return LocalFile()
} }
let serverUrl = urlForTrack(item: item, track: track) let serverUrl = urlForTrack(item: item, track: track)
@ -59,6 +58,7 @@ public class AbsDownloader: CAPPlugin {
let localUrl = itemDirectory.appendingPathComponent("\(filename)") let localUrl = itemDirectory.appendingPathComponent("\(filename)")
downloadTrack(serverUrl: serverUrl, localUrl: localUrl) downloadTrack(serverUrl: serverUrl, localUrl: localUrl)
return LocalFile(filename: filename, localUrl: localUrl)
} }
private func urlForTrack(item: LibraryItem, track: AudioTrack) -> URL { private func urlForTrack(item: LibraryItem, track: AudioTrack) -> URL {
@ -83,7 +83,7 @@ public class AbsDownloader: CAPPlugin {
return itemDirectory return itemDirectory
} }
private func downloadTrack(serverUrl: URL, localUrl: URL) -> URLSessionDownloadTask { private func downloadTrack(serverUrl: URL, localUrl: URL) {
let downloadTask = URLSession.shared.downloadTask(with: serverUrl) { urlOrNil, responseOrNil, errorOrNil in let downloadTask = URLSession.shared.downloadTask(with: serverUrl) { urlOrNil, responseOrNil, errorOrNil in
guard let fileURL = urlOrNil else { return } guard let fileURL = urlOrNil else { return }
@ -100,8 +100,6 @@ public class AbsDownloader: CAPPlugin {
// Start the download // Start the download
downloadTask.resume() downloadTask.resume()
return downloadTask
} }
} }

View file

@ -37,7 +37,7 @@ struct MediaType: Codable {
var metadata: Metadata var metadata: Metadata
var coverPath: String? var coverPath: String?
var tags: [String]? var tags: [String]?
var audioFiles: [AudioTrack]? var audioFiles: [AudioFile]?
var chapters: [Chapter]? var chapters: [Chapter]?
var tracks: [AudioTrack]? var tracks: [AudioTrack]?
var size: Int64? var size: Int64?

View file

@ -30,13 +30,13 @@ class LocalLibraryItem: Object {
super.init() super.init()
} }
init(item: LibraryItem, localUrl: URL, server: ServerConnectionConfig) { init(item: LibraryItem, localUrl: URL, server: ServerConnectionConfig, files: [LocalFile]) {
super.init() super.init()
self.id = item.id self.id = item.id
self.contentUrl = localUrl.absoluteString self.contentUrl = localUrl.absoluteString
self.mediaType = item.mediaType self.mediaType = item.mediaType
self.media = LocalMediaType(mediaType: item.media) self.media = LocalMediaType(mediaType: item.media)
// TODO: self.localFiles self.localFiles.append(objectsIn: files)
// TODO: self.coverContentURL // TODO: self.coverContentURL
// TODO: self.converAbsolutePath // TODO: self.converAbsolutePath
self.libraryItemId = item.id self.libraryItemId = item.id
@ -67,28 +67,24 @@ class LocalMediaType: Object {
super.init() super.init()
self.libraryItemId = mediaType.libraryItemId self.libraryItemId = mediaType.libraryItemId
self.metadata = LocalMetadata(metadata: mediaType.metadata) self.metadata = LocalMetadata(metadata: mediaType.metadata)
// TODO: self.coverPath
self.tags.append(objectsIn: mediaType.tags ?? []) self.tags.append(objectsIn: mediaType.tags ?? [])
self.audioFiles.append(objectsIn: mediaType.audioFiles!.enumerated().map() {
i, audioFile -> LocalAudioFile in LocalAudioFile(audioFile: audioFile)
})
self.chapters.append(objectsIn: mediaType.chapters!.enumerated().map() {
i, chapter -> LocalChapter in LocalChapter(chapter: chapter)
})
self.tracks.append(objectsIn: mediaType.tracks!.enumerated().map() {
i, track in LocalAudioTrack(track: track)
})
self.size = mediaType.size self.size = mediaType.size
self.duration = mediaType.duration self.duration = mediaType.duration
// TODO: self.episodes
self.autoDownloadEpisodes = mediaType.autoDownloadEpisodes self.autoDownloadEpisodes = mediaType.autoDownloadEpisodes
} }
} }
class LocalMediaItem: Object {
@Persisted var id: String
@Persisted var name: String
@Persisted var mediaType: String
@Persisted var folderId: String
@Persisted var contentUrl: String
@Persisted var simplePath: String
@Persisted var basePath: String
@Persisted var absolutePath: String
@Persisted var audioTracks: List<LocalAudioTrack>
@Persisted var localFiles: List<LocalFile>
@Persisted var coverContentUrl: String? = ""
@Persisted var coverAbsolutePath: String? = ""
}
class LocalMetadata: Object { class LocalMetadata: Object {
@Persisted var title: String @Persisted var title: String
@Persisted var subtitle: String? = "" @Persisted var subtitle: String? = ""
@ -135,7 +131,7 @@ class LocalMetadata: Object {
} }
} }
class LocalPodcastEpisode: Object, Codable { class LocalPodcastEpisode: Object {
@Persisted var id: String @Persisted var id: String
@Persisted var index: Int @Persisted var index: Int
@Persisted var episode: String? = "" @Persisted var episode: String? = ""
@ -154,6 +150,16 @@ class LocalAudioFile: Object, Codable {
@Persisted var index: Int @Persisted var index: Int
@Persisted var ino: String @Persisted var ino: String
@Persisted var metadata: LocalFileMetadata? @Persisted var metadata: LocalFileMetadata?
override init() {
super.init()
}
init(audioFile: AudioFile) {
self.index = audioFile.index
self.ino = audioFile.ino
// TODO: self.metadata
}
} }
class LocalAuthor: Object, Codable { class LocalAuthor: Object, Codable {
@ -181,7 +187,7 @@ class LocalChapter: Object, Codable {
} }
} }
class LocalAudioTrack: Object, Codable { class LocalAudioTrack: Object {
@Persisted var index: Int? = nil @Persisted var index: Int? = nil
@Persisted var startOffset: Double? = nil @Persisted var startOffset: Double? = nil
@Persisted var duration: Double @Persisted var duration: Double
@ -189,10 +195,25 @@ class LocalAudioTrack: Object, Codable {
@Persisted var contentUrl: String? = "" @Persisted var contentUrl: String? = ""
@Persisted var mimeType: String @Persisted var mimeType: String
@Persisted var metadata: LocalFileMetadata? = nil @Persisted var metadata: LocalFileMetadata? = nil
@Persisted var isLocal: Bool @Persisted var isLocal: Bool = true
@Persisted var localFileId: String? = "" @Persisted var localFileId: String? = ""
// var audioProbeResult: AudioProbeResult? // Needed for local playback. Requires local FFMPEG? Not sure how doable this is on iOS
@Persisted var serverIndex: Int? = nil @Persisted var serverIndex: Int? = nil
override init() {
super.init()
}
init(track: AudioTrack) {
self.index = track.index
self.startOffset = track.startOffset
self.duration = track.duration
self.title = track.title
self.contentUrl = track.contentUrl // TODO: Different URL
self.mimeType = track.mimeType
// TODO: self.metadata
// TODO: self.localFileId
self.serverIndex = track.serverIndex
}
} }
class LocalFileMetadata: Object, Codable { class LocalFileMetadata: Object, Codable {
@ -211,6 +232,20 @@ class LocalFile: Object {
@Persisted var simplePath: String @Persisted var simplePath: String
@Persisted var mimeType: String? = "" @Persisted var mimeType: String? = ""
@Persisted var size: Int64 @Persisted var size: Int64
override init() {
super.init()
}
init(filename: String, localUrl: URL) {
self.filename = filename
self.contentUrl = localUrl.absoluteString
// TODO: self.baseUrl
self.absolutePath = localUrl.absoluteString
self.simplePath = localUrl.path
// TODO: self.mimeType
// TODO: self.size
}
} }
class LocalMediaProgress: Object, Codable { class LocalMediaProgress: Object, Codable {