Search code examples
androidandroid-camera2android-cameraxandroid-mediacodec

CameraX - crash app on onPause() while recording video


if minimize app while recording video - everything all right, but once I deploy the application, ерут getting this error:

E/AndroidRuntime: FATAL EXCEPTION: CameraX-video encoding thread
Process: <pkgname>, PID: 12340
java.lang.IllegalStateException
    at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
    at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2698)
    at androidx.camera.core.VideoCapture.videoEncode(VideoCapture.java:604)
    at androidx.camera.core.VideoCapture$2.run(VideoCapture.java:348)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:214)
    at android.os.HandlerThread.run(HandlerThread.java:65)

Or if I stopped recording on onPause videoCapture?.stopRecording(), then getting this error:

E/AndroidRuntime: FATAL EXCEPTION: CameraX-
Process: <pkgname>, PID: 9489
java.lang.IllegalStateException
    at androidx.core.util.Preconditions.checkState(Preconditions.java:96)
    at androidx.core.util.Preconditions.checkState(Preconditions.java:108)
    at androidx.camera.camera2.impl.Camera.openCaptureSession(Camera.java:874)
    at androidx.camera.camera2.impl.Camera.onUseCaseReset(Camera.java:625)
    at androidx.camera.camera2.impl.Camera$11.run(Camera.java:611)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:214)
    at android.os.HandlerThread.run(HandlerThread.java:65)

How right stop record video while minimize app???

here's my code: I collect configurations:

CameraX.unbindAll()
    getDisplayMetrics()
    setPreviewConfig()

    when (typeCapture) {
        TYPE_IMAGE -> {
            setImageCapture()
            CameraX.bindToLifecycle(this, preview, imageCapture)
        }
        TYPE_VIDEO -> {
            setVideoCapture()
            CameraX.bindToLifecycle(this, preview, videoCapture)
        }
    }

set videoConfig and videoCapture:

val videoCaptureConfig = VideoCaptureConfig.Builder().apply {
        setLensFacing(lensFacing)
        setTargetAspectRatioCustom(screenAspectRatio)
        setTargetRotation(rotation)
    }.build()

    videoCapture = VideoCapture(videoCaptureConfig)

then I start recording video:

videoCapture?.startRecording(videoFile, 
CameraXExecutors.mainThreadExecutor(), recordListener)

on onPause() the errors I get are described above

Thanks


Solution

  • I had the same error when stoping the video on onPause. To solve it I added a delay before to call super.onPause() ( see : android: camera onPause/onResume issue).

    1. Declare videoSavedListener
    private VideoCapture.OnVideoSavedListener videoSavedListener= new VideoCapture.OnVideoSavedListener() {
        @Override
        public void onVideoSaved(@NonNull File file) {
            if(isRecording) {
                isRecording = false;
                // Do whatever you want
            }
        }
    
        @Override
        public void onError(@NonNull VideoCapture.VideoCaptureError videoCaptureError, @NonNull String message, @Nullable Throwable cause) {
    
        }
    };
    
    1. Add onClickListener
    button.setOnClickListener(v -> {
        if(!isRecording){
            videoCapture.startRecording(videoFile, CameraXExecutors.mainThreadExecutor(), videoSavedListener);
            isRecording = true;
         }else{
            videoCapture.stopRecording();
         }
    });
    
    1. Override onPause()
        @SuppressLint("RestrictedApi")
        @Override
        public void onPause() {
            if(isRecording){
                isRecording = false;
                videoCapture.stopRecording();
    
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                super.onPause();
            }else
                super.onPause();
        }
    

    Please note that video recording use case is currently marked as hidden in the API and is in a very preliminary state and subject to change.

    EDIT: With some devices the app still crash when calling onPause() with the videoCapture use case set. I added CameraX.unbindAll() to remove all the use cases before calling super.onPause(). Then, in the onResume() method I bind them again.