implement player callback

This commit is contained in:
Christian Schabesberger 2024-07-10 17:59:55 +02:00
parent 70d7f55cf6
commit 03ac3b5f16
4 changed files with 87 additions and 25 deletions

View File

@ -46,6 +46,12 @@ class PlayerFragment() : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
viewModel.listener = object:VideoPlayerViewModel.Listener{
override fun contentRatioChagned(ratio: Float) {
println("gurken ratio is: $ratio")
}
}
val view = inflater.inflate(R.layout.player_framgent, container, false) val view = inflater.inflate(R.layout.player_framgent, container, false)
val composeView = view.findViewById<ComposeView>(R.id.player_copose_view) val composeView = view.findViewById<ComposeView>(R.id.player_copose_view)

View File

@ -21,7 +21,7 @@
package net.newpipe.newplayer.model package net.newpipe.newplayer.model
import android.app.Application import android.app.Application
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
import androidx.media3.common.Player import androidx.media3.common.Player
@ -29,18 +29,19 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import net.newpipe.newplayer.R import net.newpipe.newplayer.R
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import net.newpipe.newplayer.utils.VideoSize
data class VideoPlayerUIState( data class VideoPlayerUIState(
val playing: Boolean, val playing: Boolean,
var fullscreen: Boolean, var fullscreen: Boolean,
var uiVissible: Boolean var uiVissible: Boolean
){ ) {
companion object { companion object {
val DEFAULT = VideoPlayerUIState( val DEFAULT = VideoPlayerUIState(
playing = true, playing = false,
fullscreen = false, fullscreen = false,
uiVissible = false uiVissible = false
) )
@ -50,15 +51,20 @@ data class VideoPlayerUIState(
interface VideoPlayerViewModel { interface VideoPlayerViewModel {
val player: Player? val player: Player?
val uiState: StateFlow<VideoPlayerUIState> val uiState: StateFlow<VideoPlayerUIState>
var listener: Listener?
fun play() fun play()
fun pause() fun pause()
fun uiResume()
fun prevStream() fun prevStream()
fun nextStream() fun nextStream()
fun switchToFullscreen() fun switchToFullscreen()
fun switchToEmbeddedView() fun switchToEmbeddedView()
interface Listener {
fun contentRatioChagned(ratio: Float)
}
} }
@HiltViewModel @HiltViewModel
class VideoPlayerViewModelImpl @Inject constructor( class VideoPlayerViewModelImpl @Inject constructor(
private val savedStateHandle: SavedStateHandle, private val savedStateHandle: SavedStateHandle,
@ -74,28 +80,54 @@ class VideoPlayerViewModelImpl @Inject constructor(
override val uiState = mutableUiState.asStateFlow() override val uiState = mutableUiState.asStateFlow()
override var listener: VideoPlayerViewModel.Listener? = null
var current_video_size = VideoSize.DEFAULT
init { init {
player.prepare() player.prepare()
player.addListener(object : Player.Listener {
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)
println("gurken playerstate: $isPlaying")
mutableUiState.update {
it.copy(playing = isPlaying)
}
}
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
super.onMediaItemTransition(mediaItem, reason)
println("gurken mediaitem transition")
val videoSize = VideoSize.fromMedia3VideoSize(player.videoSize)
val hight = player.videoSize.height
val width = player.videoSize.width
println("gurken videoSize: $videoSize, currentSize: $width, $hight")
TODO("DEN DIRNENSOHN FIXEN")
if(current_video_size != videoSize) {
if(current_video_size.getRatio() != videoSize.getRatio()) {
listener?.contentRatioChagned(videoSize.getRatio())
}
current_video_size = videoSize
}
}
})
player.setMediaItem(MediaItem.fromUri(app.getString(R.string.ccc_6502_video))) player.setMediaItem(MediaItem.fromUri(app.getString(R.string.ccc_6502_video)))
player.playWhenReady = true
} }
override fun play() { override fun play() {
println("gurken Play")
player.play() player.play()
mutableUiState.update {
it.copy(playing = player.isPlaying)
}
} }
override fun pause() { override fun pause() {
println("gurken pause")
player.pause() player.pause()
mutableUiState.update {
it.copy(playing = player.isPlaying)
}
}
override fun uiResume() {
play()
} }
override fun prevStream() { override fun prevStream() {
@ -126,6 +158,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
val dummy = object : VideoPlayerViewModel { val dummy = object : VideoPlayerViewModel {
override val player = null override val player = null
override val uiState = MutableStateFlow(VideoPlayerUIState.DEFAULT) override val uiState = MutableStateFlow(VideoPlayerUIState.DEFAULT)
override var listener: VideoPlayerViewModel.Listener? = null
override fun play() { override fun play() {
println("dummy impl") println("dummy impl")
} }
@ -142,10 +175,6 @@ class VideoPlayerViewModelImpl @Inject constructor(
println("dummy pause") println("dummy pause")
} }
override fun uiResume() {
println("dummy ui resume")
}
override fun prevStream() { override fun prevStream() {
println("dummy impl") println("dummy impl")
} }

View File

@ -78,13 +78,10 @@ fun VideoPlayerUI(
}, update = { }, update = {
when (lifecycle) { when (lifecycle) {
Lifecycle.Event.ON_PAUSE -> { Lifecycle.Event.ON_PAUSE -> {
println("gurken state on pause")
viewModel.pause() viewModel.pause()
} }
Lifecycle.Event.ON_RESUME -> {
viewModel.uiResume()
}
else -> Unit else -> Unit
} }
}) })
@ -92,7 +89,7 @@ fun VideoPlayerUI(
val isPlaying = viewModel.player!!.isPlaying val isPlaying = viewModel.player!!.isPlaying
println("is Player playing: $isPlaying") println("is Player playing: $isPlaying")
VideoPlayerControllerUI( VideoPlayerControllerUI(
isPlaying = viewModel.player?.isPlaying ?: false, isPlaying = uiState.playing,
isFullscreen = uiState.fullscreen, isFullscreen = uiState.fullscreen,
play = viewModel::play, play = viewModel::play,
pause = viewModel::pause, pause = viewModel::pause,

View File

@ -0,0 +1,30 @@
package net.newpipe.newplayer.utils
data class VideoSize(
val width: Int,
val height: Int,
/// The width/height ratio of a single pixel
val pixelWidthHeightRatio: Float
) {
override fun equals(other: Any?) =
when (other) {
is VideoSize ->
other.width == this.width && other.height == this.height && pixelWidthHeightRatio == other.pixelWidthHeightRatio
else -> false
}
override fun hashCode() =
width + height * 9999999 + (pixelWidthHeightRatio*10000).toInt()
fun getRatio() =
(width * pixelWidthHeightRatio) / height
companion object {
val DEFAULT = VideoSize(0, 0, 1F)
fun fromMedia3VideoSize(videoSize: androidx.media3.common.VideoSize) =
VideoSize(videoSize.width, videoSize.height, videoSize.pixelWidthHeightRatio)
}
}