Video can only play once
Thanks for the great library. I use this library for purpose of the ability to play video in a recyclerview. I disable auto play. But I found that when I play the video manually using the helper.play() and helper.pause() function, the first time the video is played normally. When the video is completed playing, and I try to play it again, the ToroPlayer.EventListener immediate called onComplete. Why is that? Also, when I swipe another item and swipe back, the video can be played again. Below is my implementation.(The VideoViewHolder part).
fullscreenGalleryContainer.apply {
adapter = galleryAdapter
layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
snapHelper.attachToRecyclerView(this)
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
handleScroll()
}
})
playerSelector = PlayerSelector.NONE
cacheManager = CacheManager.DEFAULT
}
package com.doki.launcher.adapter.viewholder
import android.net.Uri
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.ToggleButton
import com.doki.launcher.R
import com.doki.launcher.adapter.adaptermodel.GalleryModel
import com.doki.launcher.utils.extension.setAnimatedOnClickListner
import com.google.android.exoplayer2.ui.PlayerView
import im.ene.toro.ToroPlayer
import im.ene.toro.ToroUtil.visibleAreaOffset
import im.ene.toro.exoplayer.ExoPlayerViewHelper
import im.ene.toro.media.PlaybackInfo
import im.ene.toro.widget.Container
import kotlinx.android.synthetic.main.item_fullscreen_video.view.*
import kotlinx.android.synthetic.main.item_gallery_image.view.*
import java.io.File
interface GalleryViewHolder {
fun bindViews(isFullscreen: Boolean, position: Int, galleryModel: GalleryModel, clickListener: (GalleryModel, View, Int) -> Unit, longClickListener: (GalleryModel) -> Boolean)
}
class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), GalleryViewHolder {
override fun bindViews(isFullscreen: Boolean, position: Int, galleryModel: GalleryModel, clickListener: (GalleryModel, View, Int) -> Unit, longClickListener: (GalleryModel) -> Boolean) = with(itemView) {
galleryImageThumbnail.setImageBitmap((galleryModel as GalleryModel.GalleryImageModel).imageThumbnail)
if (isFullscreen){
setOnClickListener { clickListener(galleryModel, itemView.findViewById(R.id.galleryImageThumbnail), position) }
} else {
setAnimatedOnClickListner { clickListener(galleryModel, itemView.findViewById(R.id.galleryImageThumbnail), position) }
}
setOnLongClickListener { longClickListener(galleryModel) }
}
}
class VideoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), GalleryViewHolder, ToroPlayer {
var helper: ExoPlayerViewHelper? = null
var mediaUri: Uri? = null
var listener: ToroPlayer.EventListener? = null
val videoPlayerView = itemView.findViewById<PlayerView>(R.id.videoPlayerView)
val playPauseToggle = itemView.findViewById<ToggleButton>(R.id.playPauseToggle)
val thumbnail = itemView.findViewById<ImageView>(R.id.galleryVideoThumbnail)
override fun getPlayerView() = videoPlayerView
override fun getCurrentPlaybackInfo() = helper?.latestPlaybackInfo ?: PlaybackInfo()
override fun initialize(container: Container, playbackInfo: PlaybackInfo) {
if (helper == null) helper = ExoPlayerViewHelper(this, mediaUri!!, null)
listener = object: ToroPlayer.EventListener {
override fun onBuffering() {
Log.v("VIDEO", "onBuffering")
}
override fun onPlaying() {
Log.v("VIDEO", "onPlaying")
}
override fun onPaused() {
Log.v("VIDEO", "onPaused")
}
override fun onCompleted() {
Log.v("VIDEO", "onCompleted")
playPauseToggle.isChecked = false
thumbnail.visibility = View.VISIBLE
}
}
helper!!.addPlayerEventListener(listener!!)
helper!!.initialize(container, playbackInfo)
}
override fun play() {
helper!!.play()
}
override fun pause() {
helper!!.pause()
}
override fun isPlaying() = helper?.isPlaying ?: false
override fun release() {
if (listener != null) {
helper?.removePlayerEventListener(listener)
listener = null
}
helper?.release()
helper = null
}
override fun wantsToPlay() = visibleAreaOffset(this, itemView.parent) >= 0.65
override fun getPlayerOrder() = adapterPosition
override fun bindViews(isFullscreen: Boolean, position: Int, galleryModel: GalleryModel, clickListener: (GalleryModel, View, Int) -> Unit, longClickListener: (GalleryModel) -> Boolean) = with(itemView) {
thumbnail.setImageBitmap((galleryModel as GalleryModel.GalleryVideoModel).videoThumbnail)
if (isFullscreen){
mediaUri = Uri.fromFile(File(galleryModel.filePath))
setOnClickListener { clickListener(galleryModel, thumbnail, position) }
playPauseToggle.setOnClickListener {
if (helper?.isPlaying!!){
helper?.pause()
} else {
thumbnail.visibility = View.INVISIBLE
helper?.play()
}
}
// playPauseToggle.setOnCheckedChangeListener { buttonView, isChecked ->
// if(isChecked){
// thumbnail.visibility = View.INVISIBLE
// helper?.play()
// } else {
// if(helper?.isPlaying!!) {
// helper?.pause()
// } else {
// thumbnail.visibility = View.VISIBLE
// }
// }
// }
} else {
setAnimatedOnClickListner { clickListener(galleryModel, itemView.findViewById(R.id.galleryVideoThumbnail), position) }
}
setOnLongClickListener { longClickListener(galleryModel) }
}
}
class CameraViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), GalleryViewHolder {
override fun bindViews(isFullscreen: Boolean, position: Int, galleryModel: GalleryModel, clickListener: (GalleryModel, View, Int) -> Unit, longClickListener: (GalleryModel) -> Boolean) {
itemView.setAnimatedOnClickListner { clickListener(galleryModel, itemView, position) }
// setOnLongClickListener { longClickListener(galleryModel) }
}
}
Thanks, Kit
I found that if I seek the player to 0ms, the video can be played. Seems that oncomplete does not reset the seek progress
@dokiKit From what I remember now, after onComplete is called, the Player state becomes 'IDLE', which requires it to prepare again to be able to start another playback. If you use helper as standalone, try to call prepare/initialize again and see if it helps.
How you seek ? @dokiKit