Android MediaRecorder setCaptureRate()和视频播放速度

时间:2013-06-04 01:11:25

标签: android ffmpeg video-capture frame-rate mediarecorder

我有一个MediaRecorder录制视频,我对setCaptureRate()的效果感到困惑。

具体来说,我按照以下方式准备我的MediaRecorder:

mMediaRecorder = new MediaRecorder();
mCamera.stopPreview();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setProfile(CamcorderProfile.QUALITY_TIME_LAPSE_480P);
mMediaRecorder.setCaptureRate(30f);
mMediaRecorder.setOrientationHint(270);
mMediaRecorder.setOutputFile(...);
mMediaRecorder.setPreviewDisplay(...);
mMediaRecorder.prepare();

我录制了五秒钟(使用CountDownTimer,但这无关紧要),这是生成的文件:

$ ffmpeg -i ~/CaptureRate30fps.mp4 
...
Seems stream 0 codec frame rate differs from container frame rate: 180000.00 (180000/1) -> 30.00 (30/1)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/mspitz/CaptureRate30fps.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 0
    compatible_brands: isom3gp4
    creation_time   : 2013-06-04 00:52:00
  Duration: 00:00:02.59, start: 0.000000, bitrate: 5238 kb/s
    Stream #0.0(eng): Video: h264 (Baseline), yuv420p, 720x480, 5235 kb/s, PAR 65536:65536 DAR 3:2, 30 fps, 30 tbr, 90k tbn, 180k tbc
    Metadata:
      creation_time   : 2013-06-04 00:52:00

请注意,持续时间仅为3秒左右。该视频播放速度也快得多,就像5秒的视频被塞进3中一样。

现在,如果我通过完全如上所述准备我的mediaRecorder进行录制,但是减去setCaptureRate(30f)行,我得到一个这样的文件:

$ ffmpeg -i ~/NoSetCaptureRate.mp4 
...
Seems stream 0 codec frame rate differs from container frame rate: 180000.00 (180000/1) -> 90000.00 (180000/2)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/mspitz/NoSetCaptureRate.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 0
    compatible_brands: isom3gp4
    creation_time   : 2013-06-04 00:50:41
  Duration: 00:00:04.87, start: 0.000000, bitrate: 2803 kb/s
    Stream #0.0(eng): Video: h264 (Baseline), yuv420p, 720x480, 2801 kb/s, PAR 65536:65536 DAR 3:2, 16.01 fps, 90k tbr, 90k tbn, 180k tbc
    Metadata:
      creation_time   : 2013-06-04 00:50:41

请注意,持续时间是预期的,大约5秒。视频也以正常速度播放。

我正在使用setCaptureRate(30f),因为每秒30帧是我的CamcorderProfile videoFrameRate的值。在我的Galaxy Nexus S2(4.2.1)上,省略setCaptureRate()很好,但是当我在Galaxy Nexus S3(4.1.1)上测试时,省略setCaptureRate()会导致无用的“start failed -2​​2”错误当我打电话给mMediaRecorder.start()时。

那么,我错过了什么?我认为捕获率和视频帧速率是独立的,但很明显它们不是。有没有办法以编程方式确定我需要设置捕获率,以确定我的视频以1倍的速度播放?

3 个答案:

答案 0 :(得分:1)

(这是原始问题评论中的决议摘要)

问题可能是直接使用QUALITY_TIME_LAPSE_480P配置文件影响播放率,因为时间间隔隐含的不是1倍播放率。

此外,如果您使用该配置文件的原因是为了防止在使用QUALITY_480P时录制音频(因为时间间隔不录制音频),您可能需要拨打CamcorderProfile.get(QUALITY_480P)并根据个人资料手动设置MediaRecorder上的视频参数,而无需直接调用MediaRecorder.setProfile。没有设置任何音频参数的MediaRecorder理论上不应记录任何音频。

答案 1 :(得分:0)

根据文档,setCaptureRate(double fps)用于设置时间间隔录制,忽略音频。如果你想要比系统实际提供的更少的fps,它是最有用的。你问的fps比系统提供的更多,这里引用developer.android.com/reference

  

请注意,录像机无法保证会捕获帧   由于相机/编码器的限制,以给定的速率。然而它尝试   尽可能接近。

您的代码未调用的内容为setVideoFrameRate(int rate)。我相信使用此功能,您的录音将被修复。

答案 2 :(得分:0)

你是对的。我会给你正确答案。我遇到同样的情况。开始失败-22属于帧率。你给出的捕获率不在设备的范围内。 首先使用getSupportedPreviewFpsRange()确定设备fps范围,然后相应地设置。您可以使用PREVIEW_FPS_MAX_INDEX和PREVIEW_FPS_MIN_INDEX获取最大和最小fFps。

使用以下代码,它将给出结果乘以1000,即如果帧速率为5,则返回5000.

Camera.Parameters camParameter = camera.getParameters();
    List<int[]> frame = camParameter.getSupportedPreviewFpsRange();
        Iterator<int[]> supportedPreviewFpsIterator = frame.iterator();
        while (supportedPreviewFpsIterator.hasNext()) {
            int[] tmpRate = supportedPreviewFpsIterator.next();
            StringBuffer sb = new StringBuffer();
            sb.append("supportedPreviewRate: ");
            for (int i = tmpRate.length, j = 0; j < i; j++) {
                sb.append(tmpRate[j] + ", ");
            }
            Log.d(VTAG, sb.toString());
        }
    }

有关详情,请点击此处:http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPreviewFpsRange()

修改 在android开发者文档中。提到setCaptureRate()设置视频帧捕获率。这可用于设置与录制视频的播放速率不同的视频帧捕获速率。该方法还将记录模式设置为时间流逝。由于它还将记录模式设置为时间间隔,因此在将setprofile QUALITY_TIME_LAPSE_480P移除到任何其他支持的普通配置文件(如QUALITY_480P)后检查视频,或通过设置视频大小等来制作纯自定义mediaRecorder设置。它可能对您有所帮助。