之前简单练习过Exoplayer,当前只是简单写一下,后面就再也没涉及此处。不过最近写起来了从而记录下。
1.Kotlin–VideoView
videoView结合自定义进度条,切换后台停止,再次打开时自动播放
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/contentLayout"
android:layout_width="343dp"
android:layout_height="212dp"
android:layout_marginStart="16dp"
android:layout_marginTop="193dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed">
<VideoView
android:id="@+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/startImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/main_home_video_play"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"
tools:ignore="ContentDescription" />
<ProgressBar
android:id="@+id/startPro"
android:layout_width="40dp"
android:layout_height="40dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/pauseImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/main_home_video_play"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<LinearLayout
android:id="@+id/seekbarLina"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:id="@+id/currentTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
app:layout_constraintLeft_toLeftOf="parent"
tools:text="00.00" />
<SeekBar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:max="0"
android:maxHeight="3.4dp"
android:minHeight="3.4dp"
android:progress="0"
android:progressDrawable="@drawable/bg_video_seek_bar"
android:secondaryProgress="0"
android:thumb="@drawable/bg_video_seek_bar_thumb2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/currentTv" />
<TextView
android:id="@+id/endTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
app:layout_constraintLeft_toLeftOf="parent"
tools:text="00.00" />
</LinearLayout>-->
</androidx.constraintlayout.widget.ConstraintLayout>
private lateinit var mVideoView: VideoView
private lateinit var mCurrentTv: TextView
private lateinit var mEndTv: TextView
private lateinit var mSeekbar: SeekBar
private lateinit var mCancel: ImageView
private lateinit var mPauseImg: ImageView
private lateinit var mStartImg: ImageView
private lateinit var mStartPro: ProgressBar
private lateinit var mSeekbarLinar: LinearLayout
private var isPlay = true
private var startInt = 0
private var total = 0
val handler: Handler = @SuppressLint("HandlerLeak")
object : Handler() {
}
var runnable: Runnable = object : Runnable {
override fun run() {
progress() //执行更新
if (!isPlay) {
handler.postDelayed(this, 500)
}
}
}
override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) {
super.onViewCreated(rootView, savedInstanceState)
mVideoView = rootView.findViewById(R.id.video)
mCurrentTv = rootView.findViewById(R.id.currentTv)
mEndTv = rootView.findViewById(R.id.endTv)
mSeekbar = rootView.findViewById(R.id.seekbar)
mCancel = rootView.findViewById(R.id.cancel)
mStartImg = rootView.findViewById(R.id.startImg)
mPauseImg = rootView.findViewById(R.id.pauseImg)
mSeekbarLinar = rootView.findViewById(R.id.seekbarLina)
mStartPro = rootView.findViewById(R.id.startPro)//等待加载
playStart()
val uri = Uri.parse(“视频地址”)
mVideoView.setVideoURI(uri)
//开始播放
mStartImg.setOnClickListener {
if (isPlay) playStart()
}
//点击视频暂停
mVideoView.setOnTouchListener { _, _ ->
if (mVideoView.isPlaying) {
mPauseImg.visibility = View.VISIBLE
mStartPro.visibility = View.GONE//等待加载圈
mVideoView.pause()
isPlay = true
}
false
}
//点击暂停按钮
mPauseImg.setOnClickListener {
if (isPlay) playStart()
}
mVideoView.setOnPreparedListener { mediaPlayer ->
mediaPlayer.setOnInfoListener(MediaPlayer.OnInfoListener { _, what, _ ->
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
mStartPro.visibility = View.GONE//等待加载圈
}
return@OnInfoListener false
})
}
//监听seekBar
mSeekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
//进度已更改
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
progress()
mVideoView.seekTo(progress)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {}
override fun onStopTrackingTouch(seekBar: SeekBar) {}
})
//在视频没有初始化之前禁止拖动
mSeekbar.setOnTouchListener { _, _ ->
total == 0
}
//监听videoView是否播放完成
mVideoView.setOnCompletionListener { dismiss() }
}
private fun playStart() {
showsDialog
mStartImg.visibility = View.GONE
mPauseImg.visibility = View.GONE
mSeekbarLinar.visibility = View.VISIBLE
mStartPro.visibility = View.VISIBLE//等待加载圈
mVideoView.start()
isPlay = false
handler.postDelayed(runnable, 500)
}
//更新视频播放进度
private fun progress() {
startInt = mVideoView.currentPosition //现在的播放位置
if (total <= 0) {
total = mVideoView.duration //总的播放长度
mSeekbar.max = total
}
mCurrentTv.text = transformationDate(startInt)
mEndTv.text = transformationDate(total)
mSeekbar.progress = startInt
}
//转换字符
private fun changeString(num: Int): String {
return if (num in 0..9) "0$num" else "" + num
}
//转换时分秒
private fun transformationDate(times: Int): String {
var second = times / 1000
val time = second / 3600
val branch = second / 60
second %= 60
return changeString(time) + ":" + changeString(branch) + ":" + changeString(second)
}
override fun onPause() {
super.onPause()
if (startInt != 0) {
mVideoView.pause()
isPlay = true
startInt = mVideoView.currentPosition
handler.removeCallbacks(runnable)
}
}
override fun onStart() {
super.onStart()
if (startInt != 0) {
isPlay = false
mVideoView.start()
mVideoView.seekTo(startInt)
mStartImg.visibility = View.GONE
mPauseImg.visibility = View.GONE
handler.postDelayed(runnable, 500)
}
}
override fun onDestroyView() {
super.onDestroyView()
handler.removeCallbacks(runnable)
}
}