Merge branch 'bugfix/74-add-track-playing-logs' into 'develop'
74: Add logs for queue management See merge request funkwhale/funkwhale-android!66
This commit is contained in:
commit
759ded5ae1
|
@ -0,0 +1,46 @@
|
||||||
|
package audio.funkwhale.ffa.playback
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import audio.funkwhale.ffa.R
|
||||||
|
import audio.funkwhale.ffa.utils.OAuth
|
||||||
|
import audio.funkwhale.ffa.utils.Settings
|
||||||
|
import com.google.android.exoplayer2.upstream.DataSource
|
||||||
|
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
|
||||||
|
import com.google.android.exoplayer2.upstream.FileDataSource
|
||||||
|
import com.google.android.exoplayer2.upstream.cache.Cache
|
||||||
|
import com.google.android.exoplayer2.upstream.cache.CacheDataSource
|
||||||
|
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory
|
||||||
|
import com.google.android.exoplayer2.util.Util
|
||||||
|
|
||||||
|
class CacheDataSourceFactoryProvider(
|
||||||
|
private val oAuth: OAuth,
|
||||||
|
private val exoCache: Cache,
|
||||||
|
private val exoDownloadCache: Cache
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun create(context: Context): CacheDataSourceFactory {
|
||||||
|
|
||||||
|
val playbackCache =
|
||||||
|
CacheDataSourceFactory(exoCache, createDatasourceFactory(context, oAuth))
|
||||||
|
|
||||||
|
return CacheDataSourceFactory(
|
||||||
|
exoDownloadCache,
|
||||||
|
playbackCache,
|
||||||
|
FileDataSource.Factory(),
|
||||||
|
null,
|
||||||
|
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDatasourceFactory(context: Context, oAuth: OAuth): DataSource.Factory {
|
||||||
|
val http = DefaultHttpDataSourceFactory(
|
||||||
|
Util.getUserAgent(context, context.getString(R.string.app_name))
|
||||||
|
)
|
||||||
|
return if (!Settings.isAnonymous()) {
|
||||||
|
OAuth2DatasourceFactory(context, http, oAuth)
|
||||||
|
} else {
|
||||||
|
http
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,54 +2,13 @@ package audio.funkwhale.ffa.playback
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import audio.funkwhale.ffa.R
|
|
||||||
import audio.funkwhale.ffa.utils.*
|
import audio.funkwhale.ffa.utils.*
|
||||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
|
||||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource
|
import com.google.android.exoplayer2.source.ConcatenatingMediaSource
|
||||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
||||||
import com.google.android.exoplayer2.upstream.DataSource
|
|
||||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
|
|
||||||
import com.google.android.exoplayer2.upstream.FileDataSource
|
|
||||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource
|
|
||||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory
|
|
||||||
import com.google.android.exoplayer2.upstream.cache.Cache
|
|
||||||
import com.google.android.exoplayer2.util.Util
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import org.koin.java.KoinJavaComponent.inject
|
import org.koin.java.KoinJavaComponent.inject
|
||||||
|
|
||||||
class CacheDataSourceFactoryProvider(
|
|
||||||
private val oAuth: OAuth,
|
|
||||||
private val exoCache: Cache,
|
|
||||||
private val exoDownloadCache: Cache
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun create(context: Context): CacheDataSourceFactory {
|
|
||||||
|
|
||||||
val playbackCache =
|
|
||||||
CacheDataSourceFactory(exoCache, createDatasourceFactory(context, oAuth))
|
|
||||||
|
|
||||||
return CacheDataSourceFactory(
|
|
||||||
exoDownloadCache,
|
|
||||||
playbackCache,
|
|
||||||
FileDataSource.Factory(),
|
|
||||||
null,
|
|
||||||
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createDatasourceFactory(context: Context, oAuth: OAuth): DataSource.Factory {
|
|
||||||
val http = DefaultHttpDataSourceFactory(
|
|
||||||
Util.getUserAgent(context, context.getString(R.string.app_name))
|
|
||||||
)
|
|
||||||
return if (!Settings.isAnonymous()) {
|
|
||||||
OAuth2DatasourceFactory(context, http, oAuth)
|
|
||||||
} else {
|
|
||||||
http
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class QueueManager(val context: Context) {
|
class QueueManager(val context: Context) {
|
||||||
|
|
||||||
private val cacheDataSourceFactoryProvider: CacheDataSourceFactoryProvider by inject(
|
private val cacheDataSourceFactoryProvider: CacheDataSourceFactoryProvider by inject(
|
||||||
|
@ -89,7 +48,9 @@ class QueueManager(val context: Context) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun replace(tracks: List<Track>) {
|
fun replace(tracks: List<Track>) {
|
||||||
|
tracks.map { it.formatted }.log("Replacing queue with ${tracks.size} tracks")
|
||||||
val factory = cacheDataSourceFactoryProvider.create(context)
|
val factory = cacheDataSourceFactoryProvider.create(context)
|
||||||
val sources = tracks.map { track ->
|
val sources = tracks.map { track ->
|
||||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||||
|
@ -107,6 +68,7 @@ class QueueManager(val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun append(tracks: List<Track>) {
|
fun append(tracks: List<Track>) {
|
||||||
|
tracks.map { it.formatted }.log("Appending ${tracks.size} tracks")
|
||||||
val factory = cacheDataSourceFactoryProvider.create(context)
|
val factory = cacheDataSourceFactoryProvider.create(context)
|
||||||
val missingTracks = tracks.filter { metadata.indexOf(it) == -1 }
|
val missingTracks = tracks.filter { metadata.indexOf(it) == -1 }
|
||||||
|
|
||||||
|
@ -125,6 +87,7 @@ class QueueManager(val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun insertNext(track: Track) {
|
fun insertNext(track: Track) {
|
||||||
|
track.let { it.formatted }.log("Next track")
|
||||||
val factory = cacheDataSourceFactoryProvider.create(context)
|
val factory = cacheDataSourceFactoryProvider.create(context)
|
||||||
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
val url = mustNormalizeUrl(track.bestUpload()?.listen_url ?: "")
|
||||||
|
|
||||||
|
@ -143,6 +106,7 @@ class QueueManager(val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(track: Track) {
|
fun remove(track: Track) {
|
||||||
|
track.formatted.log("Removing track")
|
||||||
metadata.indexOf(track).let {
|
metadata.indexOf(track).let {
|
||||||
if (it < 0) {
|
if (it < 0) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -24,35 +24,67 @@ abstract class OtterResponse<D : Any> {
|
||||||
abstract fun getData(): List<D>
|
abstract fun getData(): List<D>
|
||||||
}
|
}
|
||||||
|
|
||||||
data class UserResponse(override val count: Int, override val next: String?, val results: List<Artist>) : OtterResponse<Artist>() {
|
data class UserResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: List<Artist>
|
||||||
|
) : OtterResponse<Artist>() {
|
||||||
override fun getData() = results
|
override fun getData() = results
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ArtistsResponse(override val count: Int, override val next: String?, val results: List<Artist>) : OtterResponse<Artist>() {
|
data class ArtistsResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: List<Artist>
|
||||||
|
) : OtterResponse<Artist>() {
|
||||||
override fun getData() = results
|
override fun getData() = results
|
||||||
}
|
}
|
||||||
|
|
||||||
data class AlbumsResponse(override val count: Int, override val next: String?, val results: AlbumList) : OtterResponse<Album>() {
|
data class AlbumsResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: AlbumList
|
||||||
|
) : OtterResponse<Album>() {
|
||||||
override fun getData() = results
|
override fun getData() = results
|
||||||
}
|
}
|
||||||
|
|
||||||
data class TracksResponse(override val count: Int, override val next: String?, val results: List<Track>) : OtterResponse<Track>() {
|
data class TracksResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: List<Track>
|
||||||
|
) : OtterResponse<Track>() {
|
||||||
override fun getData() = results
|
override fun getData() = results
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FavoritedResponse(override val count: Int, override val next: String?, val results: List<Favorited>) : OtterResponse<Int>() {
|
data class FavoritedResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: List<Favorited>
|
||||||
|
) : OtterResponse<Int>() {
|
||||||
override fun getData() = results.map { it.track }
|
override fun getData() = results.map { it.track }
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PlaylistsResponse(override val count: Int, override val next: String?, val results: List<Playlist>) : OtterResponse<Playlist>() {
|
data class PlaylistsResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: List<Playlist>
|
||||||
|
) : OtterResponse<Playlist>() {
|
||||||
override fun getData() = results
|
override fun getData() = results
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PlaylistTracksResponse(override val count: Int, override val next: String?, val results: List<PlaylistTrack>) : OtterResponse<PlaylistTrack>() {
|
data class PlaylistTracksResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: List<PlaylistTrack>
|
||||||
|
) : OtterResponse<PlaylistTrack>() {
|
||||||
override fun getData() = results
|
override fun getData() = results
|
||||||
}
|
}
|
||||||
|
|
||||||
data class RadiosResponse(override val count: Int, override val next: String?, val results: List<Radio>) : OtterResponse<Radio>() {
|
data class RadiosResponse(
|
||||||
|
override val count: Int,
|
||||||
|
override val next: String?,
|
||||||
|
val results: List<Radio>
|
||||||
|
) : OtterResponse<Radio>() {
|
||||||
override fun getData() = results
|
override fun getData() = results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +180,8 @@ data class Track(
|
||||||
override fun cover() = album?.cover?.urls?.original
|
override fun cover() = album?.cover?.urls?.original
|
||||||
override fun title() = title
|
override fun title() = title
|
||||||
override fun subtitle() = artist.name
|
override fun subtitle() = artist.name
|
||||||
|
|
||||||
|
val formatted: String get() = "$id $artist ($album): $title"
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Favorited(val track: Int)
|
data class Favorited(val track: Int)
|
||||||
|
|
Loading…
Reference in New Issue