package com.lizongying.mytv import android.os.Bundle import android.util.Log import android.view.LayoutInflater 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.lizongying.mytv.databinding.PlayerBinding import com.lizongying.mytv.models.TVViewModel class PlayerFragment : Fragment() { private var _binding: PlayerBinding? = null private var playerView: PlayerView? = null private var tvViewModel: TVViewModel? = null private val aspectRatio = 16f / 9f override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = PlayerBinding.inflate(inflater, container, false) playerView = _binding!!.playerView (activity as MainActivity).playerFragment = this 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") } }) } }) (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() } } override fun onStart() { Log.i(TAG, "onStart") super.onStart() if (playerView != null && playerView!!.player?.isPlaying == false) { Log.i(TAG, "replay") playerView!!.player?.prepare() } else { Log.i(TAG, "playing") } } override fun onResume() { Log.i(TAG, "onResume") super.onResume() } override fun onPause() { super.onPause() if (playerView != null && playerView!!.player?.isPlaying == true) { playerView!!.player?.stop() } } override fun onDestroy() { super.onDestroy() if (playerView != null) { playerView!!.player?.release() } } override fun onDestroyView() { super.onDestroyView() _binding = null } companion object { private const val TAG = "PlaybackVideoFragment" } }