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
Спасибо
Ответы
Ответ 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();
}