【问题标题】:Error MEDIA_ERROR_SERVER_DIED while trying to write with MediaRecord尝试使用 MediaRecord 写入时出现错误 MEDIA_ERROR_SERVER_DIED
【发布时间】:2017-11-13 12:19:43
【问题描述】:

对于大多数版本,这可以正常工作,但对于 Api 24-25,MEDIA_ERROR_SERVER_AD 错误会在录制开始时立即发生,您必须完成录制。 如果有什么具体原因,能不能处理一下,以免中断录音?

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

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

【问题讨论】:

  • 由于以下几行而发生错误:> recorder.setMaxFileSize(Long.MAX_VALUE); > recorder.setMaxDuration(Integer.MAX_VALUE);删除后一切正常。

标签: java android android-camera mediarecorder


【解决方案1】:

您可以在onError 方法中捕获MEDIA_ERROR_SERVER_DIED 消息并尝试重新实例化您的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();。之后可能需要对其应用更多设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2015-02-13
    • 2012-02-13
    • 2022-08-08
    相关资源
    最近更新 更多