SceneView / sceneview-android

SceneView is a 3D and AR Android Composable and View with Google Filament and ARCore. This is a Sceneform replacement in Kotlin
Apache License 2.0
756 stars 151 forks source link

Crash on playback of recorded session #532

Open ghostship opened 1 week ago

ghostship commented 1 week ago

When attempting to playback a recorded AR session, ARSceneView crashes with TextureNotSetException

 com.google.ar.core.exceptions.TextureNotSetException
                                                                                                        at java.lang.reflect.Constructor.newInstance0(Native Method)
                                                                                                        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
                                                                                                        at com.google.ar.core.Session.throwExceptionFromArStatus(Session.java:16)
                                                                                                        at com.google.ar.core.Session.nativeUpdate(Native Method)
                                                                                                        at com.google.ar.core.Session.update(Session.java:2)
                                                                                                        at io.github.sceneview.ar.arcore.ARSession.updateOrNull(ArSession.kt:103)
                                                                                                        at io.github.sceneview.ar.ARSceneView.onFrame(ARSceneView.kt:477)
                                                                                                        at io.github.sceneview.SceneView$FrameCallback.doFrame(SceneView.kt:876)
                                                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1035)
                                                                                                        at android.view.Choreographer.doCallbacks(Choreographer.java:845)
                                                                                                        at android.view.Choreographer.doFrame(Choreographer.java:775)
                                                                                                        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:938)
                                                                                                        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:7870)
                                                                                                        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:1003)

Recording and playback https://developers.google.com/ar/develop/java/recording-and-playback/developer-guide#kotlin

Configure session block:

configureSession { session, config ->
                if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {
                    config.depthMode = Config.DepthMode.AUTOMATIC
                } else {
                    config.depthMode = Config.DepthMode.DISABLED
                }

                config.instantPlacementMode = Config.InstantPlacementMode.DISABLED
                config.lightEstimationMode = Config.LightEstimationMode.ENVIRONMENTAL_HDR

                context.assets.open(IMAGE_DB).use { inputStream ->
                    config.augmentedImageDatabase =
                        AugmentedImageDatabase.deserialize(session, inputStream)
                }

                // Record
                if (debugState == DebugState.RECORD) {
                    val destination = Uri.fromFile(File(context.filesDir, "recording.mp4"))
                    val recordingConfig = RecordingConfig(session)
                        .setMp4DatasetUri(destination)
                        .setRecordingRotation(90)
                        .setAutoStopOnPause(true)

                    session.startRecording(recordingConfig)
                }

                // Playback
                if (debugState == DebugState.PLAYBACK) {
                    val recordingUri = Uri.fromFile(File(context.filesDir, "recording.mp4"))
                    session.setPlaybackDatasetUri(recordingUri)
                }
            }

I moving the set to an event and waiting a minute and calling:

session.pause()
session.setPlaybackDatasetUri(recordingUri)
session.resume()

and end up with the same behavior