Подтвердить что ты не робот

Android-камера 2 Api

Я пытаюсь использовать API камеры2. Я загрузил код из

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. Путь, который я использую

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

Спасибо

4b9b3361

Ответ 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

После вызова mMediaRecorder.stop() всегда появляется IllegalStateException. Я заметил, что на устройствах с INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY CameraDevice изменяет статус на ошибку, немедленно вызывая onError() в CameraDevice.StateCallback.

В примере, на который вы ссылаетесь, 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());
}

Также неплохо было бы поместить чек, чтобы убедиться, что если ошибка действительно произошла, то код с комментариями вызывается вместо того, чтобы входить в цикл, пытаясь открыть камеру снова и снова.

Протестировано на Moto G 2nd gen, с Android 5.0.2

Ответ 3

        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();
    }

это работает для меня.

Ответ 4

Это зависит от того, что вы делаете с CameraCaptureSession и MediaRecorder, но когда вы вызываете mMediaRecorder.stop(), я думаю, что он разрушает поверхность, используемую для сеанса предварительного просмотра камеры, которая вызывает эту ошибку, потому что в документации указано

Как только запись остановлена, вам придется ее снова настроить, как если бы она была только что построена.

Поэтому, если вы вызываете PreviewSession.abortCaptures() (mPreviewSession.stopRepeating(); не обязательно из того, что я собираю), он останавливает отправку камеры на поверхность рекордера, что позволит вам остановить MediaRecorder без проблем.

PreviewSession.abortCaptures(); не мгновенно останавливает вывод предварительного просмотра камеры, поэтому вам может потребоваться вызвать MediaRecorder.stop() в методе onClosed() или onReady() CameraCaptureSession.StateCallback

Ответ 5

В моем случае я использую TimerTask и Handler. Ошибка 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();
        }