Захват видео с помощью камеры2 и MediaRecorder

Я пытаюсь записать видео с двумя разными разрешениями одновременно. Иногда все идет хорошо, и иногда приложение, похоже, застряло в методах stop() 2 MediaRecorders. Может кто-нибудь PLZ просмотреть мой код, если я делаю что-то неправильно?

package com.example.android.videorecording;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.MediaCodec;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.hardware.camera2.*;
import android.os.Environment;
import android.util.Size;
import android.view.Surface;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
 CameraDevice mCamera;
 MediaRecorder mMediaRecorderLow = new MediaRecorder();
 MediaRecorder mMediaRecorderHigh = new MediaRecorder();
 CaptureRequest mCaptureRequest;
 CameraCaptureSession mSession;
 boolean recording = false;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE);
 File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
 , "Test");
 if(!dir.exists()) {
 boolean s = dir.mkdirs();
 if(!s) {
 AlertDialog.Builder alert = new AlertDialog.Builder(this);
 alert.setMessage("could not create dir");
 alert.show();
 }
 }
 final File outputFileLow = new File(dir.getAbsolutePath(), "testLow.mp4");
 final File outputFileHigh = new File(dir.getAbsolutePath(), "testHigh.mp4");
 try {
 outputFileLow.createNewFile();
 String[] cameras = manager.getCameraIdList();
 CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameras[0]);
 StreamConfigurationMap configs = characteristics.get(
 CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
 Size[] sizes = configs.getOutputSizes(MediaCodec.class);
 final Size sizeLow = sizes[5];
 final Size sizeHigh = sizes[0];
 manager.openCamera(cameras[0], new CameraDevice.StateCallback() {
 @Override
 public void onOpened(CameraDevice camera) {
 mCamera = camera;
 mMediaRecorderLow.setVideoSource(MediaRecorder.VideoSource.SURFACE);
 mMediaRecorderLow.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
 mMediaRecorderLow.***************(MediaRecorder.************.MPEG_4_SP);
 mMediaRecorderLow.setVideoSize(sizeLow.getWidth(), sizeLow.getHeight());
 mMediaRecorderLow.setMaxFileSize(0);
 mMediaRecorderLow.setOrientationHint(0);
 mMediaRecorderHigh.setVideoSource(MediaRecorder.VideoSource.SURFACE);
 mMediaRecorderHigh.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
 mMediaRecorderHigh.***************(MediaRecorder.************.MPEG_4_SP);
 mMediaRecorderHigh.setVideoSize(sizeHigh.getWidth(), sizeHigh.getHeight());
 mMediaRecorderHigh.setMaxFileSize(0);
 mMediaRecorderLow.setOrientationHint(0);
 try {
 mMediaRecorderLow.setOutputFile(outputFileLow.getAbsolutePath());
 mMediaRecorderHigh.setOutputFile(outputFileHigh.getAbsolutePath());
 mMediaRecorderLow.prepare();
 mMediaRecorderHigh.prepare();
 List<surface> list = new ArrayList<>();
 list.add(mMediaRecorderLow.getSurface());
 list.add(mMediaRecorderHigh.getSurface());
 final CaptureRequest.Builder captureRequest = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
 captureRequest.addTarget(mMediaRecorderLow.getSurface());
 captureRequest.addTarget(mMediaRecorderHigh.getSurface());
 mCaptureRequest = captureRequest.build();
 mCamera.createCaptureSession(list, new CameraCaptureSession.StateCallback() {
 @Override
 public void onConfigured(CameraCaptureSession session) {
 mSession = session;
 }
 @Override
 public void onConfigureFailed(CameraCaptureSession session) {
 mSession = session;
 }
 }, null);
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 @Override
 public void onDisconnected(CameraDevice camera) {
 }
 @Override
 public void onError(CameraDevice camera, int error) {
 }
 }, null);
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 /**
 * is called by button, should start/stop recording
 * @param v
 */
 public void trigger(View v) {
 ((Button)findViewById(R.id.button)).setText("stop"); try {
 if(!recording) {
 mMediaRecorderLow.start();
 mMediaRecorderHigh.start();
 mSession.setRepeatingRequest(mCaptureRequest,
 new CameraCaptureSession.CaptureCallback() {
 @Override
 public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
 super.onCaptureStarted(session, request, timestamp, frameNumber);
 }
 @Override
 public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
 super.onCaptureCompleted(session, request, result);
 }
 }, null);
 ((Button)findViewById(R.id.button)).setText("stop");
 recording = true;
 } else {
 ((Button)findViewById(R.id.button)).setText("start");
 recording = false;
 mSession.stopRepeating();
 mMediaRecorderHigh.stop();
 mMediaRecorderLow.stop();
 }
 } catch (CameraAccessException e) {
 e.printStackTrace();
 }
 }
}
</surface>
1 ответ

Вам также необходимо освободить MediaRecorder после его остановки. Идёт для настройки Low.Попробуйте следующий код в другой части метода Trigger.

mMediaRecorderHigh.stop();
 mMediaRecorderHigh.reset();
 mMediaRecorderHigh.release();
 mCamera.release();
 mMediaRecorderHigh= null;

licensed under cc by-sa 3.0 with attribution.