mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-31 15:47:13 +02:00
Add start of downloading library item on iOS
This commit is contained in:
@@ -13,11 +13,59 @@ public class AbsDownloader: CAPPlugin {
|
|||||||
@objc func downloadLibraryItem(_ call: CAPPluginCall) {
|
@objc func downloadLibraryItem(_ call: CAPPluginCall) {
|
||||||
let libraryItemId = call.getString("libraryItemId")
|
let libraryItemId = call.getString("libraryItemId")
|
||||||
let episodeId = call.getString("episodeId")
|
let episodeId = call.getString("episodeId")
|
||||||
let localFolderId = call.getString("localFolderId")
|
|
||||||
|
|
||||||
// TODO: Implement download
|
NSLog("Download library item \(libraryItemId ?? "N/A") episode \(episodeId ?? "")")
|
||||||
NSLog("Download library item \(libraryItemId ?? "N/A") episode \(episodeId ?? "") to folder \(localFolderId ?? "N/A")")
|
|
||||||
|
|
||||||
call.resolve()
|
ApiClient.getLibraryItemWithProgress(libraryItemId: libraryItemId!, episodeId: episodeId) { libraryItem in
|
||||||
|
if (libraryItem == nil) {
|
||||||
|
NSLog("Library item not found")
|
||||||
|
call.resolve()
|
||||||
|
} else {
|
||||||
|
NSLog("Got library item \(libraryItem!)")
|
||||||
|
|
||||||
|
// TODO: break out in seperate functions
|
||||||
|
libraryItem!.media.tracks?.forEach { track in
|
||||||
|
NSLog("TRACK \(track.contentUrl!)")
|
||||||
|
// filename needs to be encoded otherwise would just use contentUrl
|
||||||
|
let filename = track.metadata?.filename ?? ""
|
||||||
|
let filenameEncoded = filename.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
|
||||||
|
let urlstr = "\(Store.serverConfig!.address)/s/item/\(libraryItemId!)/\(filenameEncoded ?? "")?token=\(Store.serverConfig!.token)"
|
||||||
|
let url = URL(string: urlstr)!
|
||||||
|
|
||||||
|
|
||||||
|
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||||
|
let itemDirectory = documentsDirectory.appendingPathComponent("\(libraryItemId!)")
|
||||||
|
NSLog("ITEM DIR \(itemDirectory)")
|
||||||
|
|
||||||
|
// Create library item directory
|
||||||
|
do {
|
||||||
|
try FileManager.default.createDirectory(at: itemDirectory, withIntermediateDirectories: false)
|
||||||
|
} catch {
|
||||||
|
NSLog("Failed to CREATE LI DIRECTORY \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output filename
|
||||||
|
let trackFilename = itemDirectory.appendingPathComponent("\(filename)")
|
||||||
|
|
||||||
|
let downloadTask = URLSession.shared.downloadTask(with: url) { urlOrNil, responseOrNil, errorOrNil in
|
||||||
|
|
||||||
|
guard let fileURL = urlOrNil else { return }
|
||||||
|
|
||||||
|
do {
|
||||||
|
NSLog("Download TMP file URL \(fileURL)")
|
||||||
|
let imageData = try Data(contentsOf:fileURL)
|
||||||
|
try imageData.write(to: trackFilename)
|
||||||
|
NSLog("Download written to \(trackFilename)")
|
||||||
|
} catch {
|
||||||
|
NSLog("FILE ERROR: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
downloadTask.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
call.resolve()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct LibraryItem: Codable {
|
|||||||
var folderId: String
|
var folderId: String
|
||||||
var path: String
|
var path: String
|
||||||
var relPath: String
|
var relPath: String
|
||||||
|
var isFile: Bool
|
||||||
var mtimeMs: Int64
|
var mtimeMs: Int64
|
||||||
var ctimeMs: Int64
|
var ctimeMs: Int64
|
||||||
var birthtimeMs: Int64
|
var birthtimeMs: Int64
|
||||||
@@ -27,6 +28,7 @@ struct LibraryItem: Codable {
|
|||||||
var mediaType: String
|
var mediaType: String
|
||||||
var media: MediaType
|
var media: MediaType
|
||||||
var libraryFiles: [LibraryFile]
|
var libraryFiles: [LibraryFile]
|
||||||
|
var userMediaProgress:MediaProgress?
|
||||||
}
|
}
|
||||||
struct MediaType: Codable {
|
struct MediaType: Codable {
|
||||||
var libraryItemId: String?
|
var libraryItemId: String?
|
||||||
@@ -125,3 +127,15 @@ struct LibraryFile: Codable {
|
|||||||
var ino: String
|
var ino: String
|
||||||
var metadata: FileMetadata
|
var metadata: FileMetadata
|
||||||
}
|
}
|
||||||
|
struct MediaProgress:Codable {
|
||||||
|
var id:String
|
||||||
|
var libraryItemId:String
|
||||||
|
var episodeId:String?
|
||||||
|
var duration:Double
|
||||||
|
var progress:Double
|
||||||
|
var currentTime:Double
|
||||||
|
var isFinished:Bool
|
||||||
|
var lastUpdate:Int64
|
||||||
|
var startedAt:Int64
|
||||||
|
var finishedAt:Int64?
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,6 +60,27 @@ class ApiClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static func getResource<T: Decodable>(endpoint: String, decodable: T.Type = T.self, callback: ((_ param: T?) -> Void)?) {
|
||||||
|
if (Store.serverConfig == nil) {
|
||||||
|
NSLog("Server config not set")
|
||||||
|
callback?(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let headers: HTTPHeaders = [
|
||||||
|
"Authorization": "Bearer \(Store.serverConfig!.token)"
|
||||||
|
]
|
||||||
|
|
||||||
|
AF.request("\(Store.serverConfig!.address)/\(endpoint)", method: .get, encoding: JSONEncoding.default, headers: headers).responseDecodable(of: decodable) { response in
|
||||||
|
switch response.result {
|
||||||
|
case .success(let obj):
|
||||||
|
callback?(obj)
|
||||||
|
case .failure(let error):
|
||||||
|
NSLog("api request to \(endpoint) failed")
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static func startPlaybackSession(libraryItemId: String, episodeId: String?, forceTranscode:Bool, callback: @escaping (_ param: PlaybackSession) -> Void) {
|
public static func startPlaybackSession(libraryItemId: String, episodeId: String?, forceTranscode:Bool, callback: @escaping (_ param: PlaybackSession) -> Void) {
|
||||||
var endpoint = "api/items/\(libraryItemId)/play"
|
var endpoint = "api/items/\(libraryItemId)/play"
|
||||||
@@ -83,4 +104,14 @@ class ApiClient {
|
|||||||
public static func reportPlaybackProgress(report: PlaybackReport, sessionId: String) {
|
public static func reportPlaybackProgress(report: PlaybackReport, sessionId: String) {
|
||||||
try? postResource(endpoint: "api/session/\(sessionId)/sync", parameters: report.asDictionary().mapValues({ value in "\(value)" }), callback: nil)
|
try? postResource(endpoint: "api/session/\(sessionId)/sync", parameters: report.asDictionary().mapValues({ value in "\(value)" }), callback: nil)
|
||||||
}
|
}
|
||||||
|
public static func getLibraryItemWithProgress(libraryItemId:String, episodeId:String?, callback: @escaping (_ param: LibraryItem?) -> Void) {
|
||||||
|
var endpoint = "api/items/\(libraryItemId)?expanded=1&include=progress"
|
||||||
|
if episodeId != nil {
|
||||||
|
endpoint += "&episodeId=\(episodeId!)"
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiClient.getResource(endpoint: endpoint, decodable: LibraryItem.self) { obj in
|
||||||
|
callback(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user