Android MediaRecorder录制视频报错start failed:-19原因

在设置MediaRecorder参数时有设置setVideoFrameRate(int rate)或者setVideoSize(int width, int height),这两个方法代表设置录制视频的帧率和分辨率,关键在于需要手机硬件支持的,如果测试机的硬件不支持设置的参数就会无法start。

解决思路:查找手机支持的参数,选择最合适的设置进去。
针对setVideoSize(int width, int height)来举例:
通常在代码中预览布局是SurfaceView,它的大小是可控的,我们可以在其getHolder.addCallback()里获取到宽度和高度:

@Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        //根据width和height去选取Camera最优预览尺寸
    }

获取到SurfaceView宽高后,我们应该去选择一个合适的预览尺寸分辨率,选择预览尺寸的标准是(1)摄像头支持的预览尺寸的宽高比与SurfaceView的宽高比的绝对差值小于0.1;(2)在(1)获得的尺寸中,选取与SurfaceView的高的差值最小的。这里贴一下官方的代码:

public Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double) w / h;
    if (sizes == null) {
      return null;
    }
    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;
    int targetHeight = h;
    for (Camera.Size size : sizes) {
      double ratio = (double) size.width / size.height;
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
        continue;
      if (Math.abs(size.height - targetHeight) < minDiff) {
        optimalSize = size;
        minDiff = Math.abs(size.height - targetHeight);
      }
    }
    if (optimalSize == null) {
      minDiff = Double.MAX_VALUE;
      for (Camera.Size size : sizes) {
        if (Math.abs(size.height - targetHeight) < minDiff) {
          optimalSize = size;
          minDiff = Math.abs(size.height - targetHeight);
        }
      }
    }
    return optimalSize;
  }

在加载预览画面时,需要考虑Camera支持的尺寸(getSupportedPreviewSizes)和加载预览画面的SurfaceView的尺寸(layout_width/layout_height),在预览阶段,两者之间的关系直接影响清晰度及图像拉伸。对于Camera的尺寸,由于设备的硬件差异,不同设备支持的尺寸存在差异,但在默认情况(orientation=landscape)下,其width>height。以HTC609d为例,Camera支持的分辨率为1280*720(16:9)……640*480(4:3)……480*320(3:2)等十多种,而其屏幕的分辨率为960*540(16:9)。因此,很容易得到以下结论:(1)当Camera预览尺寸小于SurfaceView尺寸较多时,预览画面就不清晰;(2)Camera预览尺寸宽高比与SurfaceView宽高比相差较大时,预览画面就会拉伸。
上述代码在手机设置为横屏时并没有问题,在设置为竖屏时,为获得最优的预览尺寸,需要在调用此方法前比较SurfaceView的宽高:

if (mSupportedPreviewSizes != null) {
  mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, 
            Math.max(width, height), Math.min(width, height));
}

获得与当前SurfaceView匹配的预览尺寸后,即可通过Camera.Parameters进行设置:

Camera.Parameters mParams = mCamera.getParameters();
mParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(mParams);

就酱~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章