web-dev-qa-db-fra.com

Android Camera 2 Api

J'ai essayé camera2 API. J'ai téléchargé le code de 

https://developer.Android.com/samples/Camera2Video/index.html pour en savoir plus sur son fonctionnement. Cela fonctionne bien jusqu'à ce que je cesse d'enregistrer. Quand j'arrête d'enregistrer, le code suivant est exécuté.

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

sur mMediaRecorder.stop (); il jette l'erreur suivante

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)

Toute idée de ce que je fais mal. J'ai passé quelques heures mais je n'ai trouvé aucune solution.

Edit - J'utilise l'émulateur geneymotion. Le chemin que j'utilise 

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

Merci

20
user1154390

Ma solution est de changer void stopRecordingVideo () comme suit:

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 clé est:

    try {
    mPreviewSession.stopRepeating();
    mPreviewSession.abortCaptures();
} catch (CameraAccessException e) {
    e.printStackTrace();
} 
25
Ben Ning
        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();
    }

cela fonctionne pour moi.

3
user5399980

Après avoir appelé mMediaRecorder.stop(), IllegalStateExceptionest toujours renvoyé. J'ai remarqué que sur les appareils avec INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY, le CameraDevicechange le statut en erreur et appelle immédiatement onError() dans le CameraDevice.StateCallback.

Dans l’exemple que vous avez cité, onError() ferme la caméra et termine l’activité. Il suffit donc de modifier onError() pour rouvrir la caméra, comme suit:

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

Ce serait également une bonne idée de vérifier que si une erreur se produisait réellement, le code commenté était appelé plutôt que d'entrer dans une boucle consistant à essayer d'ouvrir la caméra encore et encore.

Testé sur une Moto G 2ème génération, avec Android 5.0.2

3
Eddie Kezeli

Dans mon cas, j'utilise TimerTask et un Handler. Il y a une erreur directement sur le mediaRecorder.stop (). Donc j'utilise cette méthode

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();
        }
0
E J Chathuranga

Cela dépend de ce que vous faites avec CameraCaptureSession et MediaRecorder, mais lorsque vous appelez mMediaRecorder.stop(), je pense que cela détruit la surface utilisée pour la session de prévisualisation de la caméra, ce qui provoque cette erreur car la documentation indique 

Une fois l'enregistrement arrêté, vous devrez le reconfigurer comme s'il venait juste d'être construit.

Par conséquent, si vous appelez PreviewSession.abortCaptures() (mPreviewSession.stopRepeating(); n'est pas nécessaire, d'après ce que je comprends), la caméra envoie la sortie à la surface de l'enregistreur, ce qui vous permet d'arrêter le MediaRecorder sans problème.

PreviewSession.abortCaptures(); n'arrête pas instantanément la sortie de prévisualisation de la caméra. Vous devrez peut-être appeler MediaRecorder.stop() dans les méthodes onClosed() ou onReady() de CameraCaptureSession.StateCallback

0
rogermushroom