diff --git a/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt b/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt index a83b1e0..0454624 100644 --- a/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt +++ b/android/src/main/java/dev/zoriya/omni/OmniPlayer.kt @@ -279,7 +279,7 @@ class OmniPlayer( override var playbackRate by mainThreadProperty( get = { player.playbackParameters.speed.toDouble() }, - set = { value -> player.setPlaybackSpeed(value.toFloat().coerceAtLeast(0f)) } + set = { value -> player.setPlaybackSpeed(value.toFloat().coerceAtLeast(0.01f)) } ) override var muted by mainThreadProperty( diff --git a/android/src/main/java/dev/zoriya/omni/OmniView.kt b/android/src/main/java/dev/zoriya/omni/OmniView.kt index 6b59711..3398e4d 100755 --- a/android/src/main/java/dev/zoriya/omni/OmniView.kt +++ b/android/src/main/java/dev/zoriya/omni/OmniView.kt @@ -219,6 +219,11 @@ class OmniView(val context: ThemedReactContext) : return } + if (boundPlayer?.isCasting == true) { + clearPictureInPictureParams() + return + } + val autoEnterEnabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && autoPip == true && @@ -242,9 +247,18 @@ class OmniView(val context: ThemedReactContext) : ) } + private fun clampedAspectRatio(width: Int, height: Int): Rational { + val minRatio = 0.42 + val maxRatio = 2.38 + val ratio = width.toDouble() / height.toDouble() + if (ratio in minRatio..maxRatio) return Rational(width, height) + val clamped = ratio.coerceIn(minRatio, maxRatio) + return Rational((clamped * 1000).toInt(), 1000) + } + private fun buildPipParams(autoEnterEnabled: Boolean): PictureInPictureParams { val aspectRatio = if (surfaceView.width > 0 && surfaceView.height > 0) { - Rational(surfaceView.width, surfaceView.height) + clampedAspectRatio(surfaceView.width, surfaceView.height) } else { Rational(16, 9) } diff --git a/android/src/main/java/dev/zoriya/omni/VlcPlayer.kt b/android/src/main/java/dev/zoriya/omni/VlcPlayer.kt index 339ed92..a314377 100644 --- a/android/src/main/java/dev/zoriya/omni/VlcPlayer.kt +++ b/android/src/main/java/dev/zoriya/omni/VlcPlayer.kt @@ -97,9 +97,11 @@ class VlcPlayer(ctx: Context) : private var mediaItems: List = emptyList() private var currentMediaItemIndex: Int = INDEX_UNSET private var currentTrackSelectionParameters = TrackSelectionParameters.Builder().build() + @Volatile private var playerError: PlaybackException? = null private var playlistMetadata: MediaMetadata = MediaMetadata.EMPTY private var userInitiatedTransition: Boolean = false + @Volatile private var cachedBufferedPosition: Long = 0L private var boundSurfaceView: SurfaceView? = null @@ -467,7 +469,11 @@ class VlcPlayer(ctx: Context) : override fun getShuffleModeEnabled(): Boolean = false - override fun isLoading() = player.playerState == IMedia.State.Opening + override fun isLoading(): Boolean { + val state = playbackState + if (state == STATE_IDLE || state == STATE_ENDED) return false + return player.playerState == IMedia.State.Opening + } override fun seekTo( mediaItemIndex: Int, @@ -493,11 +499,11 @@ class VlcPlayer(ctx: Context) : override fun getSeekForwardIncrement(): Long = 15_000L override fun setPlaybackParameters(playbackParameters: PlaybackParameters) { - player.rate = playbackParameters.speed.coerceAtLeast(0f) + player.rate = playbackParameters.speed.coerceAtLeast(0.01f) } override fun getPlaybackParameters(): PlaybackParameters = - PlaybackParameters(player.rate.coerceAtLeast(0f)) + PlaybackParameters(player.rate.takeIf { it > 0f } ?: 1f) override fun stop() { player.stop() @@ -505,6 +511,7 @@ class VlcPlayer(ctx: Context) : override fun release() { player.setEventListener(null) + listeners.release() abandonAudioFocus() player.stop() clearVideoSurface()