studio example demos camera2video autofittextureview android android-camera

demos - git android example



Android Camera 2 Api (5)

Depende de lo que esté haciendo con CameraCaptureSession y MediaRecorder, pero cuando llame a mMediaRecorder.stop() , creo que está destruyendo la superficie utilizada para la sesión de vista previa de la cámara, lo que provoca este error porque la documentación dice

Una vez que se detiene la grabación, tendrá que configurarlo de nuevo como si se hubiera construido

Por lo tanto, si llama a PreviewSession.abortCaptures() ( mPreviewSession.stopRepeating(); no es necesario de lo que recojo) detiene el envío de la cámara a la superficie de la grabadora, lo que le permitirá detener el MediaRecorder sin problemas.

PreviewSession.abortCaptures(); no detiene instantáneamente la salida de vista previa de la cámara, por lo que puede que necesite llamar a MediaRecorder.stop() en el onClosed() o onReady() de CameraCaptureSession.StateCallback

He estado probando la API de camera2. He descargado el código de

https://developer.android.com/samples/Camera2Video/index.html para aprender cómo funciona. Funciona bien hasta que deje de grabar. Cuando paro de grabar se ejecuta el siguiente código.

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

en mMediaRecorder.stop (); lanza el siguiente error

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)

Cualquier idea de lo que estoy haciendo mal. Pasé pocas horas pero no pude encontrar ninguna solución.

Editar - Estoy usando el emulador geneymotion. El camino que estoy usando

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

Gracias


Después de llamar a mMediaRecorder.stop() siempre se lanza una IllegalStateException . He notado que en los dispositivos con INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY el CameraDevice cambia de estado a error, llamando inmediatamente a onError() en CameraDevice.StateCallback .

En la muestra a la que hizo referencia, onError() cierra la cámara y finaliza la actividad, así que simplemente cambie onError() para volver a abrir la cámara, de esta manera:

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

También sería una buena idea poner un poco de control para asegurarse de que si realmente ocurrió un error, se llame al código comentado en lugar de ingresar un ciclo de intentos de abrir la cámara una y otra vez.

Probado en una Moto G de 2ª generación, con Android 5.0.2


En mi caso, uso TimerTask y un TimerTask . Hay un error directo a mMediaRecorder.stop (). Entonces uso este método

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


Mi solución es cambiar void stopRecordingVideo () de la siguiente manera:

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

}

La clave es:

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


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

Esto es trabajo para mí.