【问题标题】:Android Camera 2 Api安卓相机 2 API
【发布时间】:2015-03-10 12:29:27
【问题描述】:

我一直在尝试 camera2 API。我已经从

下载了代码

https://developer.android.com/samples/Camera2Video/index.html 了解它的工作原理。在我停止录制之前它工作正常。当我停止录制时,它会运行以下代码。

 private void stopRecordingVideo() {
        // UI
        mIsRecordingVideo = false;
        mBtn_Video.setText(R.string.record);
        // Stop recording
        try {
            mMediaRecorder.stop();
            mMediaRecorder.reset();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        Activity activity = getActivity();
        if (null != activity) {
            System.out.println("file " +  getVideoFile(activity));
            Toast.makeText(activity, "Video saved: " + getVideoFile(activity),
                    Toast.LENGTH_SHORT).show();
        }
        startPreview();

在 mMediaRecorder.stop();它抛出以下错误

01-12 16:24:23.115    2161-2200/com.cameratwoapi E/Surface﹕ queueBuffer: error queuing buffer to SurfaceTexture, -19
01-12 16:24:23.135    2161-2200/com.cameratwoapi E/EGL_emulation﹕ tid 2200: swapBuffers(285): error 0x3003 (EGL_BAD_ALLOC)
01-12 16:24:23.197    2161-2200/com.cameratwoapi E/CameraDeviceGLThread-0﹕ Received exception on GL render thread:
    java.lang.IllegalStateException: swapBuffers: EGL error: 0x3003
            at android.hardware.camera2.legacy.SurfaceTextureRenderer.checkEglError(SurfaceTextureRenderer.java:487)
            at android.hardware.camera2.legacy.SurfaceTextureRenderer.swapBuffers(SurfaceTextureRenderer.java:480)
            at android.hardware.camera2.legacy.SurfaceTextureRenderer.drawIntoSurfaces(SurfaceTextureRenderer.java:681)
            at android.hardware.camera2.legacy.GLThreadManager$1.handleMessage(GLThreadManager.java:103)
            at android.os.Handler.dispatchMessage(Handler.java:98)
            at android.os.Looper.loop(Looper.java:135)
            at android.os.HandlerThread.run(HandlerThread.java:61)

任何想法我做错了什么。我花了几个小时,但找不到任何解决方案。

编辑 - 我正在使用geneymotion 模拟器。我正在使用的路径

文件/storage/emulated/0/Android/data/com.gold.cameratwoapi/files/video.mp4

谢谢

【问题讨论】:

  • EGL 错误 0x3003 用于“错误分配”。内存出现问题...
  • 您是否尝试过调试并查看导致上述问题的具体调用?另外,由于您可能正在保存视频,您是否确保已将 WRITE_EXTERNAL_STORAGE 权限添加到您的应用程序清单文件中?
  • 谢谢大家,@Willis 我确实在清单文件中写入了权限。我正在使用此路径来存储文件 /storage/emulated/0/Android/data/com.gold.cameratwoapi/files/视频.mp4。这个问题发生在 mMediaRecorder.stop();
  • 您是否尝试过在实际设备上运行该应用程序?我过去在尝试使用模拟器保存文件时遇到过问题,即使它是允许的。
  • 我使用 Nexus 7(硬件) - 我有这个错误

标签: android android-camera


【解决方案1】:

我的解决方案是将 void stopRecordingVideo() 更改如下:

private void stopRecordingVideo() {
// UI
mIsRecordingVideo = false;
mButtonVideo.setText(R.string.record);
// Added by Ben Ning, to resolve exception issue when stop recording.
try {
    mPreviewSession.stopRepeating();
    mPreviewSession.abortCaptures();
} catch (CameraAccessException e) {
    e.printStackTrace();
} 

// Stop recording
mMediaRecorder.stop();
mMediaRecorder.reset();

}

关键是:

    try {
    mPreviewSession.stopRepeating();
    mPreviewSession.abortCaptures();
} catch (CameraAccessException e) {
    e.printStackTrace();
} 

【讨论】:

  • 它适用于我的项目,但你能详细解释一下为什么要在关闭记录器之前停止两次预览吗?
【解决方案2】:
        private void stopRecordingVideo() {
// UI
        mIsRecordingVideo = false;
        mButtonVideo.setText(R.string.record);
// Added by Ben Ning, to resolve exception issue when stop recording.
        try {
            mPreviewSession.stopRepeating();
            mPreviewSession.abortCaptures();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

// Stop recording
        mMediaRecorder.stop();
        mMediaRecorder.reset();

        Activity activity = getActivity();
        if (null != activity) {
            Toast.makeText(activity, "Video saved: " + getVideoFile(activity),
                    Toast.LENGTH_SHORT).show();
        }
        startPreview();
    }

这对我有用。

【讨论】:

    【解决方案3】:

    在调用 mMediaRecorder.stop() 之后,总是会抛出 IllegalStateException。我注意到在带有INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY 的设备上,CameraDevice 将状态更改为错误,立即在CameraDevice.StateCallback 中调用onError()

    在您引用的示例中,onError() 关闭相机并完成活动,因此只需更改 onError() 以重新打开相机,如下所示:

    @Override
    public void onError(CameraDevice cameraDevice, int error) {
        // mCameraOpenCloseLock.release();
        // cameraDevice.close();
        // mCameraDevice = null;
        // Activity activity = getActivity();
        // if (null != activity) {
        //  activity.finish();
        // }
    
        closeCamera();
        openCamera(mTextureView.getWidth(), mTextureView.getHeight());
    }
    

    最好在其中进行一些检查,以确保如果确实发生了错误,注释掉的代码会被调用,而不是进入一个反复尝试打开相机的循环。

    在装有 Android 5.0.2 的 Moto G 第二代上测试

    【讨论】:

      【解决方案4】:

      这取决于您对 CameraCaptureSession 和 MediaRecorder 所做的事情,但是当您调用 mMediaRecorder.stop() 时,我认为它正在破坏用于相机预览会话的表面,这会导致此错误,因为文档说

      一旦停止录制,您将不得不重新配置它,就像它刚刚构建一样

      因此,如果您调用 PreviewSession.abortCaptures()(根据我收集的信息,mPreviewSession.stopRepeating(); 不是必需的)它会停止相机将输出发送到记录器表面,这将使您可以毫无问题地停止 MediaRecorder。

      PreviewSession.abortCaptures(); 不会立即停止相机预览输出,因此您可能会发现您需要在 onClosed()onReady()CameraCaptureSession.StateCallback 方法中调用 MediaRecorder.stop()

      【讨论】:

        【解决方案5】:

        就我而言,我使用TimerTaskHandler。直接指向 mMediaRecorder.stop() 的错误。所以我用这个方法

        final Handler mTimerHandler = new Handler(Looper.getMainLooper());
        
                mIsRecordingVideo = false;
                // Stop recording
                try {
                    mPreviewSession.stopRepeating();
                    mPreviewSession.abortCaptures();
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                try{
                    Timer timer = new Timer();
                    TimerTask timerTask = new TimerTask() {
                        @Override
                        public void run() {
                            mTimerHandler.post(new Runnable() {
                                @Override
                                public void run() {
        
                                    mMediaRecorder.stop();
                                    mMediaRecorder.reset();
                                }
        
                            });
                        }
                    };
                    timer.schedule(timerTask,30);
                }catch(RuntimeException e){
                    Log.e("----------------","---->>>>>>>>>"+e);
                    e.printStackTrace();
                }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-26
          • 2011-05-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多