2015-01-12 2 views
14

Я пробовал camera2 API. Я скачал код отAndroid Camera 2 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(); 

at 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

Благодарность

+0

Ошибка EGL 0x3003 для «Bad alloc». Что-то не так происходит в памяти ... – shkschneider

+0

Вы пробовали отлаживать и видеть, какой именно вызов вызывает вышеупомянутые проблемы? Кроме того, поскольку вы, вероятно, сохраняете свое видео, обеспечили ли вы, что вы добавили разрешение 'WRITE_EXTERNAL_STORAGE' в ​​файл манифеста приложения? – Willis

+0

Спасибо, @Willis. Я написал разрешение в файле манифеста. Я использую этот путь для хранения файла /storage/emulated/0/Android/data/com.gold.cameratwoapi/files/video.mp4. Эта проблема возникает при mMediaRecorder.stop(); – user1154390

ответ

3

После вызова mMediaRecorder.stop()IllegalStateException всегда выброшен. Я заметил, что на устройствах с INFO_SUPPORTED_HARDWARE_LEVEL_LEGACYCameraDevice изменяет состояние на ошибку, сразу же вызывает 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 2-го поколения с Android 5.0.2

21

Мое решение изменить недействительным 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(); 
} 
+0

Он работает над моим проектом, но вы можете объяснить более подробно, почему нужно останавливать просмотр дважды перед закрытием рекордера? – fxp

0

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

После остановки записи, вы должны настроить его снова, как будто он только что был построен

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

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

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

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

0

В моем случае я использую 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(); 
     }