Leanback: update Player and add SeekDataProvider

This commit is contained in:
Felix 2019-06-07 00:31:06 +02:00
parent 75fd535390
commit 6ddb42aa85
3 changed files with 65 additions and 50 deletions

View file

@ -8,42 +8,18 @@ import android.support.v17.leanback.widget.PlaybackControlsRow
import com.google.android.exoplayer2.ext.leanback.LeanbackPlayerAdapter
import java.util.concurrent.TimeUnit
class ChaosMediaPlayerGlue(
context: Context,
playerAdapter: LeanbackPlayerAdapter
) :
class ChaosMediaPlayerGlue(context: Context, playerAdapter: LeanbackPlayerAdapter):
PlaybackTransportControlGlue<LeanbackPlayerAdapter>(context, playerAdapter) {
private val mSkipPreviousAction = PlaybackControlsRow.SkipPreviousAction(context)
private val mSkipNextAction = PlaybackControlsRow.SkipNextAction(context)
private val mFastForwardAction = PlaybackControlsRow.FastForwardAction(context)
private val mRewindAction = PlaybackControlsRow.RewindAction(context)
private val mRepeatAction = PlaybackControlsRow.RepeatAction(context)
private val mThumbsUpAction = PlaybackControlsRow.ThumbsUpAction(context)
private val mThumbsDownAction = PlaybackControlsRow.ThumbsDownAction(context)
init {
mThumbsUpAction.index = PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE
mThumbsDownAction.index = PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE
}
override fun onCreatePrimaryActions(adapter: ArrayObjectAdapter) {
// Order matters, super.onCreatePrimaryActions() will create the play / pause action.
// Will display as follows:
// play/pause, previous, rewind, fast forward, next
// > /|| |< << >> >|
super.onCreatePrimaryActions(adapter)
adapter.add(mSkipPreviousAction)
adapter.add(mRewindAction)
adapter.add(mFastForwardAction)
adapter.add(mSkipNextAction)
}
override fun onCreateSecondaryActions(adapter: ArrayObjectAdapter) {
super.onCreateSecondaryActions(adapter)
// adapter.add(mThumbsDownAction)
adapter.add(mThumbsUpAction)
// adapter.add(mRepeatAction)
}
override fun onActionClicked(action: Action) {
@ -57,20 +33,13 @@ class ChaosMediaPlayerGlue(
// Should dispatch actions that the super class does not supply callbacks for.
private fun shouldDispatchAction(action: Action): Boolean {
return (action === mRewindAction ||
action === mFastForwardAction ||
// || action === mRepeatAction
// || action === mThumbsDownAction
action === mThumbsUpAction)
return (action === mThumbsUpAction)
}
private fun dispatchAction(action: Action) {
// Primary actions are handled manually.
if (action === mRewindAction) {
rewind()
} else if (action === mFastForwardAction) {
fastForward()
} else if (action === mThumbsUpAction) {
if (action === mThumbsUpAction) {
// TODO create watchlist entry
} else if (action is PlaybackControlsRow.MultiAction) {
action.nextIndex()
// Notify adapter of action changes to handle secondary actions, such as, thumbs up/down
@ -93,21 +62,6 @@ class ChaosMediaPlayerGlue(
}
}
/** Skips backwards 10 seconds. */
fun rewind() {
var newPosition = currentPosition - THIRTY_SECONDS
newPosition = if (newPosition < 0) 0 else newPosition
playerAdapter.seekTo(newPosition)
}
/** Skips forward 10 seconds. */
fun fastForward() {
if (duration > -1) {
var newPosition = currentPosition + THIRTY_SECONDS
newPosition = if (newPosition > duration) duration else newPosition
playerAdapter.seekTo(newPosition)
}
}
companion object {
private val THIRTY_SECONDS = TimeUnit.SECONDS.toMillis(30)

View file

@ -0,0 +1,58 @@
package de.nicidienase.chaosflix.leanback.detail
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.support.v17.leanback.media.PlaybackGlue
import android.support.v17.leanback.widget.PlaybackSeekDataProvider
class ChaosflixSeekDataProvider(val context: Context, val length: Long, val thumb: String) :
PlaybackSeekDataProvider() {
private val positions: LongArray by lazy {
listOf(0,length/4,length/2,3*length/4,length).toLongArray()
}
override fun getSeekPositions(): LongArray {
return positions
}
override fun getThumbnail(index: Int, callback: ResultCallback?) {
val bitmap = Bitmap.createBitmap(160, 160, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
val paint = Paint()
paint.textSize = 16F
paint.color = Color.BLUE
canvas.drawColor(Color.YELLOW)
canvas.drawText(positions[index].toString()
, 10F, 150F, paint)
callback?.onThumbnailLoaded(bitmap, index)
}
companion object {
fun setSeekProvider(
glue: ChaosMediaPlayerGlue,
context: Context,
length: Long,
thumb: String
) {
if (glue.isPrepared) {
glue.seekProvider = ChaosflixSeekDataProvider(context, length, thumb)
glue.isSeekEnabled = true
} else {
glue.addPlayerCallback(object : PlaybackGlue.PlayerCallback() {
override fun onPreparedStateChanged(glue: PlaybackGlue?) {
if (glue?.isPrepared == true) {
glue.removePlayerCallback(this)
(glue as ChaosMediaPlayerGlue).seekProvider =
ChaosflixSeekDataProvider(context, length, thumb)
glue.isSeekEnabled = true
}
}
})
}
}
}
}

View file

@ -120,6 +120,8 @@ class EventDetailsFragment : DetailsSupportFragment() {
detailsBackgroundController.enableParallax()
playerGlue = buildPlayerGlue()
playerGlue.title = event?.title ?: room?.display
playerGlue.subtitle = event?.subtitle ?: ""
detailsBackgroundController.setupVideoPlayback(playerGlue)
when (eventType) {
@ -153,6 +155,7 @@ class EventDetailsFragment : DetailsSupportFragment() {
actionAdapter.notifyItemRangeChanged(actionAdapter.indexOf(watchlistAction), 1)
}
})
ChaosflixSeekDataProvider.setSeekProvider(playerGlue,requireContext(),event.length,event.thumbUrl)
}
detailsOverview.actionsAdapter = actionAdapter