diff --git a/core/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt b/core/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt index dc8ea21d..ad9b9d19 100644 --- a/core/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt +++ b/core/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIDefinition.kt @@ -229,6 +229,19 @@ interface SubsonicAPIDefinition { @Header("Range") offset: Long? = null ): Call + @Streaming + @GET("download.view") + fun download( + @Query("id") id: String, + @Query("maxBitRate") maxBitRate: Int? = null, + @Query("format") format: String? = null, + @Query("timeOffset") timeOffset: Int? = null, + @Query("size") videoSize: String? = null, + @Query("estimateContentLength") estimateContentLength: Boolean? = null, + @Query("converted") converted: Boolean? = null, + @Header("Range") offset: Long? = null + ): Call + @GET("jukeboxControl.view") fun jukeboxControl( @Query("action") action: JukeboxAction, diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt index 7ee29a55..dd264641 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/CachedMusicService.kt @@ -275,9 +275,10 @@ class CachedMusicService(private val musicService: MusicService) : MusicService, override fun getDownloadInputStream( song: MusicDirectory.Entry, offset: Long, - maxBitrate: Int + maxBitrate: Int, + save: Boolean ): Pair { - return musicService.getDownloadInputStream(song, offset, maxBitrate) + return musicService.getDownloadInputStream(song, offset, maxBitrate, save) } @Throws(Exception::class) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt index f8e88257..d5ff1bb0 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadFile.kt @@ -250,8 +250,9 @@ class DownloadFile( if (needsDownloading) { // Attempt partial HTTP GET, appending to the file if it exists. - val (inStream, partial) = musicService - .getDownloadInputStream(song, partialFile.length(), desiredBitRate) + val (inStream, partial) = musicService.getDownloadInputStream( + song, partialFile.length(), desiredBitRate, save + ) inputStream = inStream @@ -337,8 +338,8 @@ class DownloadFile( // Download the largest size that we can display in the UI imageLoaderProvider.getImageLoader().cacheCoverArt(song) } - } catch (e: Exception) { - Timber.e(e, "Failed to get cover art.") + } catch (all: Exception) { + Timber.e(all, "Failed to get cover art.") } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MusicService.kt index 73521d6e..1a086d73 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/MusicService.kt @@ -119,10 +119,10 @@ interface MusicService { fun getDownloadInputStream( song: MusicDirectory.Entry, offset: Long, - maxBitrate: Int + maxBitrate: Int, + save: Boolean ): Pair - // TODO: Refactor and remove this call (see RestMusicService implementation) @Throws(Exception::class) fun getVideoUrl(id: String): String? diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt index 41907a82..874138ce 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/OfflineMusicService.kt @@ -465,7 +465,8 @@ class OfflineMusicService : MusicService, KoinComponent { override fun getDownloadInputStream( song: MusicDirectory.Entry, offset: Long, - maxBitrate: Int + maxBitrate: Int, + save: Boolean ): Pair { throw OfflineException("getDownloadInputStream isn't available in offline mode") } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt index b964a90c..2e850f8a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt @@ -15,6 +15,7 @@ import org.moire.ultrasonic.api.subsonic.ApiNotSupportedException import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient import org.moire.ultrasonic.api.subsonic.models.AlbumListType.Companion.fromName import org.moire.ultrasonic.api.subsonic.models.JukeboxAction +import org.moire.ultrasonic.api.subsonic.response.StreamResponse import org.moire.ultrasonic.api.subsonic.throwOnFailure import org.moire.ultrasonic.api.subsonic.toStreamResponse import org.moire.ultrasonic.data.ActiveServerProvider @@ -427,12 +428,20 @@ open class RESTMusicService( override fun getDownloadInputStream( song: MusicDirectory.Entry, offset: Long, - maxBitrate: Int + maxBitrate: Int, + save: Boolean ): Pair { val songOffset = if (offset < 0) 0 else offset + lateinit var response: StreamResponse - val response = API.stream(song.id, maxBitrate, offset = songOffset) - .execute().toStreamResponse() + // Use semantically correct call + if (save) { + response = API.download(song.id, maxBitrate, offset = songOffset) + .execute().toStreamResponse() + } else { + response = API.stream(song.id, maxBitrate, offset = songOffset) + .execute().toStreamResponse() + } response.throwOnFailure()