尝试使用MediaRecord写入时出错MEDIA_ERROR_SERVER_DIED

时间:2017-11-13 12:19:44

标签: java android android-camera mediarecorder

对于大多数版本,此工作正常,但对于Api 24-25,录制开始时您必须立即发生MEDIA_ERROR_SERVER_AD错误,并且您必须完成录制。 如果有任何具体原因,是否可以处理以免中断录音?

如果这有帮助,那么我附上代码。 Thaks!

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.BatteryManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.inject.Inject;

public class MainCameraFragment extends BaseFragment implements SurfaceHolder.Callback,
    MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {

  private static final String TAG = "MainCameraFragment";

  private static final float MIN_BATTERY_CHARGE = 0.1f;

  private Camera camera = null;
  private int cameraId = -1;
  private MediaRecorder recorder = null;
  private boolean inPreview = false;
  private Action<RecordingError> recordingErrorAction = null;

  /** Surface view container. */
  private FrameLayout container;
  /** Surface view instance. */
  private SurfaceView surfaceView;
  /** Orientation listener. */
  private OrientationEventListener orientationEventListener;
  /** Start recording time. */
  private long startRecordingTime = 0;
  /** Last video path. */
  private File lastVideoPath;

  /** Recording manager instance. */
  @Inject
  RecordingManager recordingManager;
  /** Settings manager instance. */
  @Inject
  SettingsManager settingsManager;

  /** Do on resume. */
  private Runnable doOnResume;

  public enum RecordingError {
    ILLEGAL_MEDIA_RECORDER_STATE,
    NOT_ENOUGH_MEMORY,
    NOT_ENOUGH_BATTERY,
  }

  /** Start preview from camera. */
  private void startPreview() {
    if (camera != null && !inPreview) {
      try {

        camera.setPreviewDisplay(surfaceView.getHolder());

        Camera.Parameters parameters = camera.getParameters();
        final List<Camera.Size> supportedSizes = parameters.getSupportedPreviewSizes();

        Camera.Size bestFitSize = camera.new Size(0, 0);

        for( Camera.Size size : supportedSizes ) {
          if( size.width <= surfaceView.getWidth() && size.height <= surfaceView.getHeight() ) {
            bestFitSize = size;
            break;
          }
        }

        if( bestFitSize.width == 0 && bestFitSize.height == 0 ) {
          bestFitSize = supportedSizes.get(0);
        }

        parameters.setPreviewSize(bestFitSize.width, bestFitSize.height);
        camera.setParameters(parameters);
        camera.startPreview();

        inPreview = true;
      } catch (IOException e) {
        Log.e(TAG, "Error setting camera preview: " + e.getMessage());
      }
    }
  }

  /** Stop camera preview. */
  private void stopPreview() {
    if (camera != null && inPreview) {
      try {
        camera.stopPreview();
      } catch (Exception e) {
        Log.i(TAG, "Error setting camera preview: " + e.getMessage());
      }

      inPreview = false;
    }

  }

  /** Init camera. */
  private void initCamera() {
    if (camera == null) {
      cameraId = recordingManager.getCameraId();

      if (cameraId >= 0) {
        try {
          camera = Camera.open(cameraId);

          setupCameraDisplayOrientation();

          lockAutoFocus(camera, settingsManager.isLockAutoFocus());
          lockAutoExposure(camera, settingsManager.isLockAutoExposure());
        }
        catch (Exception e) {
          Log.e(TAG, e.getMessage(), e);
        }
      } else {
        Log.e(TAG, "Can't find camera id");
      }
    }
  }

  /** Release camera. */
  private void releaseCamera() {
    if (camera != null) {
      camera.release();
      camera = null;
      cameraId = -1;
    }
  }

  /** @return recording state. */
  public boolean isRecording() {
    return recorder != null;
  }

  /** Start recording. */
  public void startRecording(final Action<RecordingError> recordingErrorAction, boolean micUsage) {
    if (camera != null && !isRecording()) {
      camera.stopPreview();
      final RecordingError recordingError = checkEnoughs();
      if (recordingError != null) {
        if (recordingErrorAction != null) {
          recordingErrorAction.act(recordingError);
        }
        return;
      }

      startRecordingTime = System.currentTimeMillis();

      final CamcorderProfile profile = recordingManager.getCamcorderProfile(cameraId, camera.getParameters());

      stopPreview();
      camera.unlock();

      MediaRecorder recorder = null;
      try {
        recorder = new MediaRecorder();
        recorder.setCamera(camera);

        recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);

        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        recorder.setProfile(profile);

        final String ts = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
        lastVideoPath = new File(recordingManager.getRecordsDirPath(), "Video_" + ts + ".mp4");
        recorder.setOutputFile(lastVideoPath.getAbsolutePath());
        final int orientationHint = getRecorderOrientationHint();
        if (orientationHint != -1) {
          recorder.setOrientationHint(orientationHint);
        }
        recorder.setMaxFileSize(Long.MAX_VALUE);
        recorder.setMaxDuration(Integer.MAX_VALUE);

        stopPreview();
        recorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
        recorder.setOnErrorListener(this);
        recorder.setOnInfoListener(this);
        recorder.prepare();
        recorder.start();

        this.recordingErrorAction = recordingErrorAction;
      } catch (IOException e) {
        Log.d(TAG, "Error " + e.getMessage(), e);
        if (recorder != null) {
          recorder.release();
          recorder = null;
        }
      } finally {
        this.recorder = recorder;
      }
    }
  }

  /** Stop recording. */
  public void stopRecording() {
    if (isRecording()) {
      final MediaRecorder recorder = this.recorder;
      this.recorder = null;

      recorder.stop();
      recorder.reset();
      recorder.release();

      this.recordingErrorAction = null;
      try {
        camera.reconnect();
        startPreview();
      } catch (IOException e) {
        Log.w(TAG, e.getMessage(), e);
      }
    }
  }

  @Override
  public void onError(final MediaRecorder mr, final int what, final int extra) {
    Log.e(TAG, "Media recorder error: " + what + " extra: " + extra);

    if (recordingErrorAction != null) {
      recordingErrorAction.act(RecordingError.ILLEGAL_MEDIA_RECORDER_STATE);
    }
  }
}

1 个答案:

答案 0 :(得分:0)

您可以在MEDIA_ERROR_SERVER_DIED方法中捕获onError消息,并尝试重新实例化recorder

public void onError(final MediaRecorder mr, final int what, final int extra) {
    Log.e(TAG, "Media recorder error: " + what + " extra: " + extra);

    if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
        Log.i(LOGTAG, "MediaPlayer died, restarting");  
        recorder.release(); 

        recorder = new MediaRecorder(); 
    }

    if (recordingErrorAction != null) {
      recordingErrorAction.act(RecordingError.ILLEGAL_MEDIA_RECORDER_STATE);
    }
}

在上面的示例代码中,我只是通过以下行recorder重新实例化recorder = new MediaRecorder();。也许它可能需要在之后应用更多设置。