mirror of
https://github.com/lizongying/my-tv.git
synced 2026-10-27 14:46:30 +08:00
163 lines
5.5 KiB
Kotlin
163 lines
5.5 KiB
Kotlin
package com.lizongying.mytv
|
|
|
|
import android.os.Bundle
|
|
import android.util.Log
|
|
import android.view.LayoutInflater
|
|
import android.view.SurfaceHolder
|
|
import android.view.SurfaceView
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.view.ViewTreeObserver
|
|
import androidx.annotation.OptIn
|
|
import androidx.fragment.app.Fragment
|
|
import androidx.media3.common.MediaItem
|
|
import androidx.media3.common.PlaybackException
|
|
import androidx.media3.common.Player
|
|
import androidx.media3.common.VideoSize
|
|
import androidx.media3.common.util.UnstableApi
|
|
import androidx.media3.exoplayer.ExoPlayer
|
|
import androidx.media3.ui.PlayerView
|
|
import com.google.android.exoplayer2.SimpleExoPlayer
|
|
import com.lizongying.mytv.databinding.PlayerBinding
|
|
import com.lizongying.mytv.models.TVViewModel
|
|
|
|
|
|
class PlayerFragment : Fragment(), SurfaceHolder.Callback {
|
|
|
|
private var _binding: PlayerBinding? = null
|
|
private var playerView: PlayerView? = null
|
|
private var tvViewModel: TVViewModel? = null
|
|
private val aspectRatio = 16f / 9f
|
|
|
|
|
|
private lateinit var surfaceView: SurfaceView
|
|
private lateinit var surfaceHolder: SurfaceHolder
|
|
private var exoPlayer: SimpleExoPlayer? = null
|
|
|
|
override fun onCreateView(
|
|
inflater: LayoutInflater, container: ViewGroup?,
|
|
savedInstanceState: Bundle?
|
|
): View {
|
|
_binding = PlayerBinding.inflate(inflater, container, false)
|
|
|
|
if (Utils.isTmallDevice()) {
|
|
_binding!!.playerView.visibility = View.GONE
|
|
surfaceView = _binding!!.surfaceView
|
|
surfaceHolder = surfaceView.holder
|
|
surfaceHolder.addCallback(this)
|
|
} else {
|
|
_binding!!.surfaceView.visibility = View.GONE
|
|
playerView = _binding!!.playerView
|
|
}
|
|
|
|
playerView?.viewTreeObserver?.addOnGlobalLayoutListener(object :
|
|
ViewTreeObserver.OnGlobalLayoutListener {
|
|
override fun onGlobalLayout() {
|
|
playerView!!.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
|
playerView!!.player = activity?.let {
|
|
ExoPlayer.Builder(it)
|
|
.build()
|
|
}
|
|
playerView!!.player?.playWhenReady = true
|
|
playerView!!.player?.addListener(object : Player.Listener {
|
|
override fun onVideoSizeChanged(videoSize: VideoSize) {
|
|
val ratio = playerView?.measuredWidth?.div(playerView?.measuredHeight!!)
|
|
if (ratio != null) {
|
|
val layoutParams = playerView?.layoutParams
|
|
if (ratio < aspectRatio) {
|
|
layoutParams?.height =
|
|
(playerView?.measuredWidth?.div(aspectRatio))?.toInt()
|
|
playerView?.layoutParams = layoutParams
|
|
} else if (ratio > aspectRatio) {
|
|
layoutParams?.width =
|
|
(playerView?.measuredHeight?.times(aspectRatio))?.toInt()
|
|
playerView?.layoutParams = layoutParams
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onPlayerError(error: PlaybackException) {
|
|
super.onPlayerError(error)
|
|
|
|
Log.e(TAG, "PlaybackException $error")
|
|
tvViewModel?.changed()
|
|
}
|
|
})
|
|
}
|
|
})
|
|
(activity as MainActivity).fragmentReady()
|
|
return _binding!!.root
|
|
}
|
|
|
|
@OptIn(UnstableApi::class)
|
|
fun play(tvViewModel: TVViewModel) {
|
|
this.tvViewModel = tvViewModel
|
|
playerView?.player?.run {
|
|
setMediaItem(MediaItem.fromUri(tvViewModel.getVideoUrlCurrent()))
|
|
prepare()
|
|
}
|
|
exoPlayer?.run {
|
|
setMediaItem(com.google.android.exoplayer2.MediaItem.fromUri(tvViewModel.getVideoUrlCurrent()))
|
|
prepare()
|
|
}
|
|
}
|
|
|
|
override fun onStart() {
|
|
Log.i(TAG, "onStart")
|
|
super.onStart()
|
|
if (playerView != null && playerView!!.player?.isPlaying == false) {
|
|
Log.i(TAG, "replay")
|
|
playerView!!.player?.prepare()
|
|
playerView!!.player?.play()
|
|
}
|
|
if (exoPlayer?.isPlaying == false) {
|
|
Log.i(TAG, "replay")
|
|
exoPlayer?.prepare()
|
|
exoPlayer?.play()
|
|
}
|
|
}
|
|
|
|
override fun onResume() {
|
|
Log.i(TAG, "onResume")
|
|
super.onResume()
|
|
}
|
|
|
|
override fun onPause() {
|
|
super.onPause()
|
|
if (playerView != null && playerView!!.player?.isPlaying == true) {
|
|
playerView!!.player?.stop()
|
|
}
|
|
if (exoPlayer?.isPlaying == true) {
|
|
exoPlayer?.stop()
|
|
}
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
super.onDestroy()
|
|
if (playerView != null) {
|
|
playerView!!.player?.release()
|
|
}
|
|
exoPlayer?.release()
|
|
}
|
|
|
|
override fun onDestroyView() {
|
|
super.onDestroyView()
|
|
_binding = null
|
|
}
|
|
|
|
companion object {
|
|
private const val TAG = "PlaybackVideoFragment"
|
|
}
|
|
|
|
override fun surfaceCreated(holder: SurfaceHolder) {
|
|
exoPlayer = SimpleExoPlayer.Builder(requireContext()).build()
|
|
exoPlayer?.setVideoSurfaceHolder(surfaceHolder)
|
|
exoPlayer?.playWhenReady = true
|
|
}
|
|
|
|
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
|
|
}
|
|
|
|
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
|
}
|
|
} |