media icon indicating copy to clipboard operation
media copied to clipboard

PlayerView inside of LazyList throws exception "ExoTimeoutException: Detaching surface timed out."

Open distinctdan opened this issue 9 months ago • 1 comments

Version

Media3 1.3.1

More version details

No response

Devices that reproduce the issue

Emulator API 33

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Not tested

Reproduction steps

  1. Use PlayerView inside of a LazyRow. I've included my code below for initializing it.
  2. Use an ExoPlayer where the media isn't connected yet. I'm simulating this using an RtspMediaSource and passing it an invalid URL so that it never connects.
  3. When the PlayerView is scrolled offscreen, it blocks the main thread for several seconds and throws ExoTimeoutException: Detaching surface timed out.

I've tried this with using the new update and onReset callbacks for AndroidView, and tried it without, and the error happens in both cases. However, the error doesn't happen if the video is successfully playing, so I'm guessing it's related to the initialization logic of the player or renderer, where it's expecting something to be initialized when the surface is detached, but it isn't initialized yet.

MyCameraTile Composable:

AndroidView(
    modifier = Modifier
        .matchParentSize()
        .padding(camPad),
    factory = { ctx ->
        PlayerView(ctx).apply {
            hideController()
            useController = false
            setShowBuffering(PlayerView.SHOW_BUFFERING_NEVER)
            resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
            layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        }
    },
    update = { view ->
        view.player = tile.player
    },
    // Allows view reuse by LazyList.
    onReset = { view ->
        // I've tried setting the player to null here and the error still happens.
    },
    onRelease = { view ->
        // I've tried setting the player to null here and the error still happens.
    }
)

Expected result

No error should be thrown.

Actual result

It throws the following error:

androidx.media3.exoplayer.ExoPlaybackException: Unexpected runtime error
    at androidx.media3.exoplayer.ExoPlayerImpl.setVideoOutputInternal(ExoPlayerImpl.java:2713)
    at androidx.media3.exoplayer.ExoPlayerImpl.access$1800(ExoPlayerImpl.java:132)
    at androidx.media3.exoplayer.ExoPlayerImpl$ComponentListener.surfaceDestroyed(ExoPlayerImpl.java:3199)
    at android.view.SurfaceView.notifySurfaceDestroyed(SurfaceView.java:1800)
    at android.view.SurfaceView.updateSurface(SurfaceView.java:993)
    at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:308)
    at android.view.View.dispatchDetachedFromWindow(View.java:21336)
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3949)
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3949)
    at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:5785)
    at androidx.compose.ui.viewinterop.AndroidViewHolder.onDeactivate(AndroidViewHolder.android.kt:205)
    at androidx.compose.ui.node.LayoutNode.onDeactivate(LayoutNode.kt:1341)
    at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1114)
    at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:828)
    at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849)
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:625)
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:537)
    at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:41)
    at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
    at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
    at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
    at android.view.Choreographer.doCallbacks(Choreographer.java:899)
    at android.view.Choreographer.doFrame(Choreographer.java:827)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7872)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: androidx.media3.exoplayer.ExoTimeoutException: Detaching surface timed out.
    at androidx.media3.exoplayer.ExoPlayerImpl.setVideoOutputInternal(ExoPlayerImpl.java:2712)
    at androidx.media3.exoplayer.ExoPlayerImpl.access$1800(ExoPlayerImpl.java:132) 
    at androidx.media3.exoplayer.ExoPlayerImpl$ComponentListener.surfaceDestroyed(ExoPlayerImpl.java:3199) 
    at android.view.SurfaceView.notifySurfaceDestroyed(SurfaceView.java:1800) 
    at android.view.SurfaceView.updateSurface(SurfaceView.java:993) 
    at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:308) 
    at android.view.View.dispatchDetachedFromWindow(View.java:21336) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3949) 
    at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3949) 
    at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:5785) 
    at androidx.compose.ui.viewinterop.AndroidViewHolder.onDeactivate(AndroidViewHolder.android.kt:205) 
    at androidx.compose.ui.node.LayoutNode.onDeactivate(LayoutNode.kt:1341) 
    at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1114) 
    at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:828) 
    at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849) 
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:625) 
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Recomposer.kt:537) 
    at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:41) 
    at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109) 
    at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41) 
    at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69) 
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229) 
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239) 
    at android.view.Choreographer.doCallbacks(Choreographer.java:899) 
    at android.view.Choreographer.doFrame(Choreographer.java:827) 
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214) 
    at android.os.Handler.handleCallback(Handler.java:942) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loopOnce(Looper.java:201) 
    at android.os.Looper.loop(Looper.java:288) 
    at android.app.ActivityThread.main(ActivityThread.java:7872) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) 

Media

Not needed, reproducible with RtspMediaSourceFactory with an invalid URL. I'm using 192.168.0.1/profile1/media.smp

Bug Report

  • [X] You will email the zip file produced by adb bugreport to [email protected] after filing this issue.

distinctdan avatar May 03 '24 19:05 distinctdan

Hi Daniel,

Would it be possibly for you to provide a minimal MainActivity.kt that shows LazyRow initialization, Player intialisation and setting of the MediaItems. I tried to reproduce the issue, but I run into issues way before I am able to swipe the videos off the screen.

Perhaps you are preparing too many Players or are trying to reuse the same Player inefficiently? Perhaps it's how you use LazyRow's item keys. Or given that the mediaItem is never fetched, PlayerView doesn't know the size of the video and hence creates a 0-pixel item, sending you into an infinite row-creation? These are just some thoughts, would be nice to debug your particular case.

oceanjules avatar May 08 '24 22:05 oceanjules

Hey @distinctdan. We need more information to resolve this issue but there hasn't been an update in 14 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot avatar May 28 '24 01:05 google-oss-bot

Since there haven't been any recent updates here, I am going to close this issue.

@distinctdan if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

google-oss-bot avatar Jun 06 '24 01:06 google-oss-bot