Do not push our own notification when Chromecast session is active. Fixed issue where PlayerService listener would trigger twice on service restart. Implemented basic queue management on Chromecast player.

This commit is contained in:
Antoine POPINEAU 2020-06-24 19:33:00 +02:00
parent 9ed7eab761
commit 080cce00ee
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
5 changed files with 60 additions and 19 deletions

View File

@ -4,10 +4,7 @@ import android.content.Context
import android.net.Uri
import android.view.Menu
import com.github.apognu.otter.playback.PlayerService
import com.github.apognu.otter.utils.AppContext
import com.github.apognu.otter.utils.CastInterface
import com.github.apognu.otter.utils.Track
import com.github.apognu.otter.utils.mustNormalizeUrl
import com.github.apognu.otter.utils.*
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.Timeline
import com.google.android.exoplayer2.ext.cast.CastPlayer
@ -58,7 +55,9 @@ class Cast(val context: Context, val switchListener: PlayerService.OnPlayerSwitc
tracks
.map { track -> buildMediaQueueItem(track) }
.apply {
castPlayer.loadItems(this.toTypedArray(), 0, 0, Player.REPEAT_MODE_OFF)
castPlayer.loadItems(this.toTypedArray(), 0, 0, Player.REPEAT_MODE_OFF).also { result ->
result?.addStatusListener { debugQueue() }
}
castPlayer.playWhenReady = true
}
}
@ -69,7 +68,9 @@ class Cast(val context: Context, val switchListener: PlayerService.OnPlayerSwitc
tracks
.map { track -> buildMediaQueueItem(track) }
.forEach {
castPlayer.addItems(it)
castPlayer.addItems(it).also { result ->
result?.addStatusListener { debugQueue() }
}
}
}
}
@ -80,7 +81,9 @@ class Cast(val context: Context, val switchListener: PlayerService.OnPlayerSwitc
player.currentTimeline.getPeriod(current + 1, this)
}
castPlayer.addItems(period.id.toString().toInt(), buildMediaQueueItem(track))
castPlayer.addItems(period.id.toString().toInt(), buildMediaQueueItem(track)).also { result ->
result?.addStatusListener { debugQueue() }
}
}
}
@ -90,7 +93,9 @@ class Cast(val context: Context, val switchListener: PlayerService.OnPlayerSwitc
player.currentTimeline.getPeriod(index, this)
}
castPlayer.removeItem(period.id.toString().toInt())
castPlayer.removeItem(period.id.toString().toInt()).also { result ->
result?.addStatusListener { debugQueue() }
}
}
}
@ -100,7 +105,29 @@ class Cast(val context: Context, val switchListener: PlayerService.OnPlayerSwitc
player.currentTimeline.getPeriod(oldPosition, this)
}
castPlayer.moveItem(period.id.toString().toInt(), newPosition)
castPlayer.moveItem(period.id.toString().toInt(), newPosition).also { result ->
result?.addStatusListener { debugQueue() }
}
}
}
private fun debugQueue() {
if (BuildConfig.DEBUG) {
player.onCast()?.let { castPlayer ->
"START queue".log()
for (index in 0 until castPlayer.currentTimeline.periodCount) {
val period = Timeline.Period().run {
player.currentTimeline.getPeriod(index, this)
}
castPlayer.getItem(period.id as Int)?.let { item ->
"${item.media.metadata.getString(MediaMetadata.KEY_ARTIST)} - ${item.media.metadata.getString(MediaMetadata.KEY_TITLE)}".log()
}
}
"END queue".log()
}
}
}

View File

@ -39,7 +39,6 @@ import com.squareup.picasso.Picasso
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.partial_now_playing.*
import kotlinx.android.synthetic.main.row_download.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope

View File

@ -158,8 +158,6 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
}
notifyItemMoved(oldPosition, newPosition)
CommandBus.send(Command.MoveFromQueue(oldPosition, newPosition))
}
inner class ViewHolder(view: View, val context: Context?) : RecyclerView.ViewHolder(view), View.OnClickListener {
@ -186,6 +184,9 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
}
inner class TouchHelperCallback : ItemTouchHelper.Callback() {
var from = -1
var to = -1
override fun isLongPressDragEnabled() = false
override fun isItemViewSwipeEnabled() = false
@ -194,7 +195,9 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0)
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
onItemMove(viewHolder.adapterPosition, target.adapterPosition)
to = target.adapterPosition
onItemMove(viewHolder.adapterPosition, to)
return true
}
@ -204,7 +207,10 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
context?.let {
viewHolder?.itemView?.background = ColorDrawable(context.getColor(R.color.colorSelected))
viewHolder?.let {
from = viewHolder.adapterPosition
viewHolder.itemView.background = ColorDrawable(context.getColor(R.color.colorSelected))
}
}
}
@ -212,6 +218,13 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
}
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
if (from != -1 && to != -1) {
CommandBus.send(Command.MoveFromQueue(from, to))
from = -1
to = -1
}
viewHolder.itemView.background = ColorDrawable(Color.TRANSPARENT)
super.clearView(recyclerView, viewHolder)

View File

@ -24,7 +24,6 @@ import com.github.apognu.otter.repositories.AlbumsRepository
import com.github.apognu.otter.repositories.ArtistTracksRepository
import com.github.apognu.otter.repositories.Repository
import com.github.apognu.otter.utils.*
import com.github.apognu.otter.views.LoadingFlotingActionButton
import com.squareup.picasso.Picasso
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
import kotlinx.android.synthetic.main.fragment_albums.*

View File

@ -59,7 +59,7 @@ class PlayerService : Service() {
private lateinit var radioPlayer: RadioPlayer
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
watchEventBus()
if (jobs.isEmpty()) watchEventBus()
return START_STICKY
}
@ -235,7 +235,10 @@ class PlayerService : Service() {
@SuppressLint("NewApi")
override fun onDestroy() {
jobs.forEach { it.cancel() }
jobs.forEach {
it.cancel()
jobs.remove(it)
}
try {
unregisterReceiver(headphonesUnpluggedReceiver)
@ -356,7 +359,7 @@ class PlayerService : Service() {
when (playWhenReady) {
true -> {
when (playbackState) {
Player.STATE_READY -> mediaControlsManager.updateNotification(queue.current(), true)
Player.STATE_READY -> player.onLocal()?.also { mediaControlsManager.updateNotification(queue.current(), true) }
Player.STATE_BUFFERING -> EventBus.send(Event.Buffering(true))
Player.STATE_ENDED -> EventBus.send(Event.PlaybackStopped)
}
@ -379,7 +382,7 @@ class PlayerService : Service() {
super.onTracksChanged(trackGroups, trackSelections)
queue.current = player.currentWindowIndex
mediaControlsManager.updateNotification(queue.current(), player.playWhenReady)
player.onLocal()?.also { mediaControlsManager.updateNotification(queue.current(), player.playWhenReady) }
if (queue.get().isNotEmpty() && queue.current() == queue.get().last() && radioPlayer.isActive()) {
GlobalScope.launch(IO) {