[M2]M2-p 视频加载优化, 先完全下载再播放

This commit is contained in:
wangmingjun
2023-02-21 18:47:48 +08:00
parent 0d084aefc2
commit dbffff0e07
6 changed files with 182 additions and 58 deletions

View File

@@ -100,7 +100,7 @@ class PM2VideoFragment :
arrayListOf.add(
RotationItem(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
1,
0,
"",
"7"
)

View File

@@ -59,12 +59,21 @@ class AdvanceGSYVideoPlayer: StandardGSYVideoPlayer {
setViewShowState(mTopContainer, GONE)
setViewShowState(mLoadingProgressBar, GONE)
setViewShowState(mThumbImageViewLayout, GONE)
setViewShowState(mThumbImageView, GONE)
setViewShowState(
mLockScreen, GONE
)
setIsTouchWiget(false)
isFocusableInTouchMode = false
}
fun setCacheImageViewVisible() {
setViewShowState(mThumbImageViewLayout, VISIBLE)
setViewShowState(mThumbImageView, VISIBLE)
}
fun setCacheImageViewGone() {
setViewShowState(mThumbImageViewLayout, GONE)
setViewShowState(mThumbImageView, GONE)
}
}

View File

@@ -6,7 +6,6 @@ import android.view.ViewGroup
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
/**
@@ -47,12 +46,12 @@ class AdvancePagerAdapter(context: Context, viewPager: ViewPager) : PagerAdapter
if (viewList.size > 0) {
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {//有人反应第一个是视频不播放这边优化了一下
Logger.d("onPageScrollStateChanged", "第一个是视频")
Logger.d(ImageAndVideoRotation.TAG, "第一个是视频")
val video = viewList[mViewPager.currentItem] as AdvanceVideoView
video.setVideo(gsySampleCallBack,mViewPager.currentItem)
video.setVideo(gsySampleCallBack)
} else if (viewList[mViewPager.currentItem] is AdvanceImageView) {
Logger.d("onPageScrollStateChanged", "startTimer()_1")
Logger.d(ImageAndVideoRotation.TAG, "startTimer()_1")
current = 0//换页重新计算时间
startTimer()
}
@@ -120,7 +119,7 @@ class AdvancePagerAdapter(context: Context, viewPager: ViewPager) : PagerAdapter
// 由于viewpager的预加载机制onPageSelected这里面加载videoview 放的跟玩一样 等操作完成后再播放videoview就香了 很丝滑
if (state == 0) { //静止,什么都没做
val currentItem = mViewPager.currentItem
Logger.d("onPageScrollStateChanged",
Logger.d(ImageAndVideoRotation.TAG,
"state = $state currentItem = $currentItem lastPosition = $lastPosition")
if (viewList.size > 1) { //多于1才会循环跳转
@@ -128,11 +127,11 @@ class AdvancePagerAdapter(context: Context, viewPager: ViewPager) : PagerAdapter
if (viewList[mViewPager.currentItem] is AdvanceVideoView) {
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.setCacheImageView()
videoView.setVideo(gsySampleCallBack,mViewPager.currentItem)
videoView.setCacheImageViewVisible()
videoView.setVideo(gsySampleCallBack)
} else if (viewList[mViewPager.currentItem] is AdvanceImageView) {
Logger.d("onPageScrollStateChanged", "startTimer()")
Logger.d(ImageAndVideoRotation.TAG, "startTimer()")
current = 0//换页重新计算时间
startTimer()
}
@@ -144,51 +143,55 @@ class AdvancePagerAdapter(context: Context, viewPager: ViewPager) : PagerAdapter
private var gsySampleCallBack = object : GSYSampleCallBack() {
override fun onPrepared(url: String?, vararg objects: Any?) {
Logger.d("onPageScrollStateChanged", "onPrepared")
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
UiThreadHandler.postDelayed({
Logger.d("onPageScrollStateChanged", "cacheImg gone")
Logger.d(ImageAndVideoRotation.TAG, "onPrepared")
if (viewList[mViewPager.currentItem] is AdvanceVideoView){
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.setCacheImageViewGone()
},1000)
}
}
override fun onAutoComplete(url: String?, vararg objects: Any?) {
Logger.d("onPageScrollStateChanged", "onAutoComplete()")
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.onVideoReset()
videoView.setCacheImageView()
goNextItemView()
Logger.d(ImageAndVideoRotation.TAG, "onAutoComplete()")
if (viewList[mViewPager.currentItem] is AdvanceVideoView){
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.onVideoReset()
videoView.setCacheImageViewVisible()
goNextItemView()
}
}
override fun onPlayError(url: String?, vararg objects: Any?) {
super.onPlayError(url, *objects)
Logger.d("onPageScrollStateChanged", "onPlayError()")
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.onVideoReset()
videoView.setCacheImageView()
goNextItemView()
Logger.d(ImageAndVideoRotation.TAG, "onPlayError()-${objects}")
if (viewList[mViewPager.currentItem] is AdvanceVideoView){
val videoView = (viewList[mViewPager.currentItem] as AdvanceVideoView)
videoView.onVideoReset()
videoView.setCacheImageViewVisible()
videoView.clearLocalErrorVideo()
goNextItemView()
}
}
}
private fun startTimer() {
if (null != thread && !thread?.isInterrupted!!) {
Logger.d("onPageScrollStateChanged", "thread.interrupt()")
Logger.d(ImageAndVideoRotation.TAG, "thread.interrupt()")
thread?.interrupt()
thread = null
}
thread = Thread {
while (null != thread && !thread?.isInterrupted!!) {
try {
Logger.d("onPageScrollStateChanged", "sleep")
Logger.d(ImageAndVideoRotation.TAG, "sleep")
Thread.sleep(1000)
if (viewList[mViewPager.currentItem] is AdvanceImageView) {
Logger.d("onPageScrollStateChanged", "增加1s")
Logger.d(ImageAndVideoRotation.TAG, "增加1s")
current += 1000
}else{
break
}
if (current >= time) {
Logger.d("onPageScrollStateChanged", "5s到跳转")
Logger.d(ImageAndVideoRotation.TAG, "5s到跳转")
goNextItemView()
current = 0
break

View File

@@ -7,12 +7,18 @@ import android.widget.ImageView
import android.widget.RelativeLayout
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.mogo.eagle.core.utilcode.breakpoint.Config
import com.mogo.eagle.core.utilcode.breakpoint.bean.ThreadBean
import com.mogo.eagle.core.utilcode.breakpoint.callback.IDownload
import com.mogo.eagle.core.utilcode.breakpoint.utils.DownloadUtils
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.BitmapHelper
import com.mogo.eagle.core.utilcode.util.FileUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.bus.passenger.R
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import java.lang.Exception
/**
* @author: wangmingjun
@@ -26,7 +32,9 @@ class AdvanceVideoView @JvmOverloads constructor(
private var cacheImage: ImageView? = null
private var videoViewPlayer: AdvanceGSYVideoPlayer? = null
private var gsyVideoOptionBuilder: GSYVideoOptionBuilder? = null
private var path: String? = null
private var mOnCompletionListener: GSYSampleCallBack? = null
private var downloadVideoName = ""
private var fileNetPath: String? = ""
init {
initView()
@@ -40,7 +48,6 @@ class AdvanceVideoView @JvmOverloads constructor(
private fun initCacheImgView() {
cacheImage = ImageView(context)
cacheImage?.scaleType = ImageView.ScaleType.FIT_XY
addView(cacheImage, LayoutParams(-1, -1))
}
private fun initVideoView() {
@@ -63,14 +70,25 @@ class AdvanceVideoView @JvmOverloads constructor(
}
fun setVideoPath(path: String) {
this.path = path
// BitmapHelper.getVideoThumbnail(path) /*获取第一帧图*/
cacheImage?.visibility = VISIBLE
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v
// https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4
this.fileNetPath = path
val pathList = path.split("/")
if (pathList.isNotEmpty()){
this.downloadVideoName = pathList[pathList.size - 1]
}
loadCacheImg()
}
private fun loadCacheImg() {
// BitmapHelper.getVideoThumbnail(path) /*获取第一帧图*/
setCacheImageViewVisible()
Thread{
var bitmap = BitmapHelper.getVideoThumbnail(path)
Logger.d("onPageScrollStateChanged", "setVideoPath")
var bitmap = BitmapHelper.getVideoThumbnail(fileNetPath)
Logger.d(ImageAndVideoRotation.TAG, "setVideoPath")
ThreadUtils.runOnUiThread {
Logger.d("onPageScrollStateChanged", "bitmap加载")
Logger.d(ImageAndVideoRotation.TAG, "bitmap加载")
cacheImage?.let {
Glide.with(context).load(bitmap)
.apply(
@@ -78,35 +96,67 @@ class AdvanceVideoView @JvmOverloads constructor(
)
.into(it)
}
videoViewPlayer?.thumbImageView = cacheImage
}
}.start()
}
@SuppressLint("CheckResult")
fun setCacheImageView() {
cacheImage?.visibility = VISIBLE
fun clearLocalErrorVideo(){
if (downloadVideoName.isNotEmpty()
&& FileUtils.isFileExists(Config.downLoadPath + downloadVideoName)){
FileUtils.delete(Config.downLoadPath + downloadVideoName)
}
}
fun setVideo(onCompletionListener: GSYSampleCallBack,position: Int) {
Logger.d("onPageScrollStateChanged", "setVideoPlay")
gsyVideoOptionBuilder = GSYVideoOptionBuilder()
gsyVideoOptionBuilder?.setUrl(path)
?.setPlayTag(path + position)
?.setCacheWithPlay(false)
?.setThumbPlay(false)
?.build(videoViewPlayer)
@SuppressLint("CheckResult")
fun setCacheImageViewVisible() {
videoViewPlayer?.setCacheImageViewVisible()
}
videoViewPlayer?.isFocusableInTouchMode = false
videoViewPlayer?.setVideoAllCallBack(onCompletionListener)
videoViewPlayer?.startPlayLogic()
fun setCacheImageViewGone() {
videoViewPlayer?.setCacheImageViewGone()
}
fun setVideo(onCompletionListener: GSYSampleCallBack) {
Logger.d(ImageAndVideoRotation.TAG, "setVideo")
mOnCompletionListener = onCompletionListener
//判断是否已经下载
if (downloadVideoName.isNotEmpty()){
if (FileUtils.isFileExists(Config.downLoadPath + downloadVideoName)){
startPlay()
return
}
startDownLoadVideo()
}
}
private fun startDownLoadVideo(){
//下载视频, 下载成功后再播放
DownloadUtils.downLoad(context,fileNetPath, Config.downLoadPath
,downloadVideoName,5,downListener)
}
private fun startPlay(){
try {
Logger.d(ImageAndVideoRotation.TAG, "startPlay")
gsyVideoOptionBuilder = GSYVideoOptionBuilder()
gsyVideoOptionBuilder?.setUrl("file:///mnt/sdcard/downloads/$downloadVideoName")
?.setPlayTag(downloadVideoName)
?.setCacheWithPlay(false)
?.setThumbPlay(false)
?.build(videoViewPlayer)
videoViewPlayer?.isFocusableInTouchMode = false
videoViewPlayer?.setVideoAllCallBack(mOnCompletionListener)
videoViewPlayer?.startPlayLogic()
}catch (e: Exception){
Logger.d(ImageAndVideoRotation.TAG, "startPlay e = ${e.message}")
}
}
fun onVideoReset(){
videoViewPlayer?.onVideoReset()
}
fun setCacheImageViewGone() {
cacheImage?.visibility = INVISIBLE
mOnCompletionListener = null
}
fun setPause() {
@@ -120,4 +170,36 @@ class AdvanceVideoView @JvmOverloads constructor(
videoViewPlayer?.startPlayLogic()
}
}
private val downListener = object : IDownload{
override fun onStart(url: String?) {
Logger.d(ImageAndVideoRotation.TAG, "download-onStart")
}
override fun onPause(url: String?, threadBean: ThreadBean?) {
Logger.d(ImageAndVideoRotation.TAG, "download-onPause")
}
override fun onProgress(url: String?, length: Int) {
Logger.d(ImageAndVideoRotation.TAG, "download-onProgress")
}
override fun onFinished(url: String?, threadBean: ThreadBean?) {
Logger.d(ImageAndVideoRotation.TAG, "download-onFinished")
//下载完成
ThreadUtils.runOnUiThread {
startPlay()
}
}
override fun onError(url: String?, errorMsg: String?) {
Logger.d(ImageAndVideoRotation.TAG, "download-onError-$errorMsg")
//出错再次下载
if (errorMsg != null) {
if (errorMsg.startsWith("initFailed")){
startDownLoadVideo()
}
}
}
}
}

View File

@@ -0,0 +1,24 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.viewpager.widget.ViewPager
/**
* @author: wangmingjun
* @date: 2023/2/21
*/
class AdvanceViewPager: ViewPager{
constructor(context: Context) : super(context)
constructor(context: Context,attrs: AttributeSet?) : super(context,attrs)
override fun onTouchEvent(ev: MotionEvent?): Boolean {
return false
}
override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return false
}
}

View File

@@ -1,5 +1,6 @@
package com.mogo.och.bus.passenger.ui.widget.video
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.widget.RelativeLayout
@@ -12,15 +13,20 @@ class ImageAndVideoRotation @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : RelativeLayout(context, attrs) {
private var viewPager: ViewPager? = null
private var viewPager: AdvanceViewPager? = null
private var pagerAdapter: AdvancePagerAdapter? = null
companion object {
const val TAG = "ImageAndVideoRotation"
}
init {
initView()
}
@SuppressLint("ClickableViewAccessibility")
private fun initView() {
viewPager = ViewPager(context)
viewPager = AdvanceViewPager(context)
pagerAdapter = AdvancePagerAdapter(context, viewPager!!)
viewPager?.adapter = pagerAdapter