mirror of
https://github.com/apognu/otter
synced 2025-02-10 16:20:36 +01:00
Changed track metadata reporting method so it could work similarly across devices (notification, ambient display, lockscreen, watches, ...) (#55).
This commit is contained in:
parent
a3f74af076
commit
b0d7ff393d
@ -18,7 +18,9 @@ import com.github.apognu.otter.utils.*
|
||||
import com.squareup.picasso.Picasso
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers.Default
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class MediaControlsManager(val context: Service, private val scope: CoroutineScope, private val mediaSession: MediaSessionCompat) {
|
||||
companion object {
|
||||
@ -30,6 +32,27 @@ class MediaControlsManager(val context: Service, private val scope: CoroutineSco
|
||||
|
||||
private var notification: Notification? = null
|
||||
|
||||
fun buildTrackMetadata(track: Track?): MediaMetadataCompat {
|
||||
track?.let {
|
||||
val coverUrl = maybeNormalizeUrl(track.album.cover.original)
|
||||
|
||||
return MediaMetadataCompat.Builder().apply {
|
||||
putString(MediaMetadataCompat.METADATA_KEY_TITLE, track.title)
|
||||
putString(MediaMetadataCompat.METADATA_KEY_ARTIST, track.artist.name)
|
||||
putLong(MediaMetadata.METADATA_KEY_DURATION, (track.bestUpload()?.duration?.toLong() ?: 0L) * 1000)
|
||||
|
||||
try {
|
||||
runBlocking(IO) {
|
||||
this@apply.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, Picasso.get().load(coverUrl).get())
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}.build()
|
||||
}
|
||||
|
||||
return MediaMetadataCompat.Builder().build()
|
||||
}
|
||||
|
||||
fun updateNotification(track: Track?, playing: Boolean) {
|
||||
if (notification == null && !playing) return
|
||||
|
||||
@ -44,17 +67,6 @@ class MediaControlsManager(val context: Service, private val scope: CoroutineSco
|
||||
val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, 0)
|
||||
|
||||
val coverUrl = maybeNormalizeUrl(track.album.cover.original)
|
||||
val cover = coverUrl?.run { Picasso.get().load(coverUrl) }
|
||||
|
||||
mediaSession.setMetadata(MediaMetadataCompat.Builder().apply {
|
||||
putString(MediaMetadata.METADATA_KEY_ARTIST, track.artist.name)
|
||||
putString(MediaMetadata.METADATA_KEY_TITLE, track.title)
|
||||
putLong(MediaMetadata.METADATA_KEY_DURATION, (track.bestUpload()?.duration?.toLong() ?: 0L) * 1000)
|
||||
|
||||
cover?.let {
|
||||
try { putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, it.get()) } catch (_: Exception) {}
|
||||
}
|
||||
}.build())
|
||||
|
||||
notification = NotificationCompat.Builder(
|
||||
context,
|
||||
@ -69,11 +81,13 @@ class MediaControlsManager(val context: Service, private val scope: CoroutineSco
|
||||
)
|
||||
.setSmallIcon(R.drawable.ottershape)
|
||||
.run {
|
||||
if (cover != null) {
|
||||
try { setLargeIcon(cover.get()) } catch (_: Exception) {}
|
||||
coverUrl?.let {
|
||||
try { setLargeIcon(Picasso.get().load(coverUrl).get()) } catch (_: Exception) {}
|
||||
|
||||
this
|
||||
} else this
|
||||
return@run this
|
||||
}
|
||||
|
||||
this
|
||||
}
|
||||
.setContentTitle(track.title)
|
||||
.setContentText(track.artist.name)
|
||||
|
@ -9,15 +9,15 @@ import android.media.AudioAttributes
|
||||
import android.media.AudioFocusRequest
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.os.ResultReceiver
|
||||
import android.support.v4.media.session.MediaSessionCompat
|
||||
import android.support.v4.media.session.PlaybackStateCompat
|
||||
import android.view.KeyEvent
|
||||
import com.github.apognu.otter.R
|
||||
import com.github.apognu.otter.utils.*
|
||||
import com.google.android.exoplayer2.C
|
||||
import com.google.android.exoplayer2.ExoPlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer
|
||||
import com.google.android.exoplayer2.*
|
||||
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray
|
||||
@ -84,6 +84,13 @@ class PlayerService : Service() {
|
||||
|
||||
mediaSession = MediaSessionCompat(this, applicationContext.packageName).apply {
|
||||
isActive = true
|
||||
setPlaybackState(PlaybackStateCompat.Builder()
|
||||
.setActions(
|
||||
PlaybackStateCompat.ACTION_PLAY_PAUSE or
|
||||
PlaybackStateCompat.ACTION_SEEK_TO or
|
||||
PlaybackStateCompat.ACTION_SKIP_TO_NEXT or
|
||||
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
|
||||
).build())
|
||||
}
|
||||
|
||||
mediaControlsManager = MediaControlsManager(this, scope, mediaSession)
|
||||
@ -97,6 +104,30 @@ class PlayerService : Service() {
|
||||
|
||||
MediaSessionConnector(mediaSession).also {
|
||||
it.setPlayer(this)
|
||||
it.setMediaMetadataProvider {
|
||||
mediaControlsManager.buildTrackMetadata(queue.current())
|
||||
}
|
||||
|
||||
it.setQueueNavigator(object : MediaSessionConnector.QueueNavigator {
|
||||
override fun onSkipToQueueItem(player: Player, controlDispatcher: ControlDispatcher, id: Long) {}
|
||||
|
||||
override fun onCurrentWindowIndexChanged(player: Player) {}
|
||||
|
||||
override fun onCommand(player: Player, controlDispatcher: ControlDispatcher, command: String, extras: Bundle?, cb: ResultReceiver?) = true
|
||||
|
||||
override fun getSupportedQueueNavigatorActions(player: Player): Long {
|
||||
return PlaybackStateCompat.ACTION_PLAY_PAUSE or PlaybackStateCompat.ACTION_SKIP_TO_NEXT or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
|
||||
}
|
||||
|
||||
override fun onSkipToNext(player: Player, controlDispatcher: ControlDispatcher) {}
|
||||
|
||||
override fun getActiveQueueItemId(player: Player?) = 0L
|
||||
|
||||
override fun onSkipToPrevious(player: Player, controlDispatcher: ControlDispatcher) {}
|
||||
|
||||
override fun onTimelineChanged(player: Player) {}
|
||||
})
|
||||
|
||||
it.setMediaButtonEventHandler { player, _, mediaButtonEvent ->
|
||||
mediaButtonEvent.extras?.getParcelable<KeyEvent>(Intent.EXTRA_KEY_EVENT)?.let { key ->
|
||||
if (key.action == KeyEvent.ACTION_UP) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user