Fix omni-view

This commit is contained in:
2026-04-20 19:53:39 +02:00
parent 4bb13739d5
commit f1112bbc8f
4 changed files with 134 additions and 115 deletions
@@ -16,7 +16,10 @@ class OmniPlayer : HybridOmniPlayerSpec() {
override val eventMap = EventMap(player)
init {
player.setOptionString("vo", "null")
// `vo` is effectively fixed after init in libmpv.
// Initializing with `null` keeps audio working but prevents video output forever.
player.setOptionString("vo", "gpu-next")
player.setOptionString("force-window", "yes")
player.setOptionString("gpu-context", "android")
player.setOptionString("opengl-es", "yes")
player.setOptionString("hwdec", "mediacodec-copy")
@@ -46,6 +49,7 @@ class OmniPlayer : HybridOmniPlayerSpec() {
}
override var source: Source by deferredObservable { _, _, new ->
Log.e("omni", "Chaning source")
player.command(arrayOf("stop"))
val src = new.src.firstOrNull() ?: return@deferredObservable
@@ -76,6 +80,11 @@ class OmniPlayer : HybridOmniPlayerSpec() {
}
}
fun setSurfaceSize(width: Int, height: Int) {
if (width <= 0 || height <= 0) return
player.setPropertyString("android-surface-size", "${width}x${height}")
}
override val hasPrev get() = source.metadata?.hasPrev ?: false
override val hasNext get() = source.metadata?.hasNext ?: false
override val status: PlayerStatus
@@ -1,61 +1,57 @@
package dev.zoriya.omni
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import android.widget.FrameLayout
import com.facebook.react.uimanager.ThemedReactContext
import com.margelo.nitro.omni.HybridOmniPlayerSpec
import com.margelo.nitro.omni.HybridOmniViewSpec
class OmniView(val context: ThemedReactContext) : HybridOmniViewSpec() {
private val surfaceView = SurfaceView(context)
class OmniView(val context: ThemedReactContext) : HybridOmniViewSpec(), SurfaceHolder.Callback {
override val view = FrameLayout(context)
private val surfaceView = SurfaceView(context).apply {
layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
)
holder.addCallback(this@OmniView)
view.addView(this)
}
private var surfaceReady = false
private var boundPlayer: OmniPlayer? = null
override val view: View = surfaceView
override lateinit var player: HybridOmniPlayerSpec
override var autoplay: Boolean? = true
override var showNotification: Boolean? = true
override var autoPip: Boolean? = true
init {
surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
surfaceReady = true
boundPlayer?.setSurface(holder.surface)
}
override fun surfaceChanged(
holder: SurfaceHolder,
format: Int,
width: Int,
height: Int
) {
surfaceReady = true
boundPlayer?.setSurface(holder.surface)
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
surfaceReady = false
boundPlayer?.setSurface(null)
}
})
}
override fun afterUpdate() {
Log.e("omniView", "After update called")
if (!::player.isInitialized) {
throw IllegalStateException("Player is null in OmniView")
Log.w("omniView", "Skipping update because player is not set yet")
return
}
val omniPlayer = player as? OmniPlayer
?: throw IllegalStateException("Player is not an OmniPlayer in OmniView")
?: run {
Log.w(
"omniView",
"Skipping update because player has unexpected type: ${player::class.java.name}"
)
return
}
if (boundPlayer !== omniPlayer) {
boundPlayer?.setSurface(null)
boundPlayer = omniPlayer
if (boundPlayer === omniPlayer) {
return;
}
Log.e("omniView", "Resetting old player")
boundPlayer?.setSurface(null)
boundPlayer = omniPlayer
if (surfaceReady) {
omniPlayer.setSurface(surfaceView.holder.surface)
}
@@ -66,10 +62,32 @@ class OmniView(val context: ThemedReactContext) : HybridOmniViewSpec() {
}
override fun onDropView() {
Log.e("omniView", "omni-view dropped")
if (!::player.isInitialized) return
val omniPlayer = player as? OmniPlayer ?: return
omniPlayer.setSurface(null)
boundPlayer = null
}
override fun surfaceCreated(holder: SurfaceHolder) {
surfaceReady = true
Log.e("omniView", "surface created")
boundPlayer?.setSurface(holder.surface)
}
override fun surfaceChanged(
holder: SurfaceHolder,
format: Int,
width: Int,
height: Int
) {
boundPlayer?.setSurfaceSize(width, height)
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
Log.e("omniView", "surface destroyed")
surfaceReady = false
boundPlayer?.setSurface(null)
}
}