2013-06-04 93 views
5

私はMediaRecorderのビデオを録画していますが、私はsetCaptureRate()の効果で非常に混乱しています。Android MediaRecorder setCaptureRate()とビデオ再生の速度

具体的には、次のように私は私のMediaRecorderを準備します。私は(CountDownTimerと、それは無関係です)5秒間録音

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

、これが生成されますファイルです:

$ 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 

Durationは約3秒です。ビデオはまた、3秒間に5秒のビデオが入っているかのように、もっと速く再生されます。

私は上記のように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秒であることに注意してください。ビデオも通常の速度で再生されます。

私はCamCorderProfileのvideoFrameRateの値が毎秒30フレームであるため、setCaptureRate(30f)を使用しています。ギャラクシーNexus S2(4.2.1)ではsetCaptureRate()を省略しても問題ありませんが、Galaxy Nexus S3(4.1.1)でテストした場合、setCaptureRate()を省略すると便利な "start failed -2​​2"というエラーが発生します私がmMediaRecorder.start()と呼んだとき。

私は何が欠けていますか?キャプチャレートとビデオフレームレートは独立していると思いましたが、そうではないことは明らかです。ビデオが1倍速で再生されることを確認するためにキャプチャレートを設定する必要があるかどうかをプログラムで判断する方法はありますか?

+0

なぜ「QUALITY_TIME_LAPSE_480P」ではなく「QUALITY_480P」でないのですか?タイムラプスは本来1倍の再生速度ではありません。 –

+0

また、 'MediaRecorder.setVideoFrameRate'を呼び出してみましたか? –

+0

@RomanNurikあなたのコメントありがとう!私は実際には音を録音したくはありません。それを行う唯一の方法は、時間経過ビデオを使用することです。 Re:setVideoFrameRate、setProfile()を呼び出すと呼び出されます:https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaRecorder.java#L329実際、ソースを見ると最初の場所でsetCaptureRate()を呼び出す必要があることを私に伝えました。 https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaRecorder.java#L337それ以外の場合は、-22を取得します。 – spitzanator

答えて

1

は、直接QUALITY_TIME_LAPSE_480Pプロファイルの影響再生速度を使用しているのかもしれ

問題(これは、元の質問にコメントから解像度の要約です)再生速度。あなたは、そのプロファイルを使用している理由は、(時間の経過は、音声を録音していないので)QUALITY_480Pを使用したときに記録されてからオーディオを防ぐためである場合

さらに、あなたの代わりにCamcorderProfile.get(QUALITY_480P)を呼び出し、MediaRecorder上のビデオパラメータを設定することもできますMediaRecorder.setProfileを直接呼び出すことなく、プロファイルに基づいて手動で実行できます。オーディオパラメータが設定されていないMediaRecorderでは、理論上はオーディオを記録してはいけません。

0

ドキュメントによると、setCaptureRate(double fps)は、オーディオを無視してタイムラプス記録を設定するために使用されます。これは、システムが実際に提供することができるより少ないfpsが必要な場合に最も便利です。レコーダーは、フレームが原因カメラ/エンコーダの制限のために与えられた速度で を捕獲されることを保証することはできませんことを

注:あなたはここにdeveloper.android.com/referenceからの引用であり、システムが提供できるよりも多くのFPSをお願いします。しかし、それは可能な限り近いように を試みます。

コードで呼び出されないものは、setVideoFrameRate(int rate)です。私はこの機能を使用すると、あなたの録音が修正されると信じています。

+0

残念ながら、それは正しくありません。 MediaRecorderのソースを見てください:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/MediaRecorder.java setProfile(CamcorderProfile profile) setVideoFrameRate(profile.videoFrameRate);を呼び出します。私がGalaxy Nexus S3で動作させるためには、最初にsetCaptureRate()を試してみました。 – spitzanator

0

あなたは正しいです。私はあなたに正しい答えを与えるでしょう。私は同じ状況に直面しています。失敗しました22フレームレートに属しています。あなたが与えているキャプチャレートはデバイスの範囲にありません。 getSupportedPreviewFpsRange()を使用して最初にデバイスのfps範囲を決定し、それに応じて設定します。最大および最小fFpsにはPREVIEW_FPS_MAX_INDEXおよびPREVIEW_FPS_MIN_INDEXを使用できます。 http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPreviewFpsRange()

EDIT: アンドロイドで

使用次のコードには、フレームレートが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()); 
     } 
    } 

を返します。つまり、1000年を掛けた結果が得られます開発者のドキュメントsetCaptureRate()は、ビデオフレームのキャプチャレートを設定します。これは、記録されたビデオの再生レートとは異なるビデオフレームキャプチャレートを設定するために使用できます。また、この方法では、録画モードを時間切れに設定します。また、録画モードをタイムラプスに設定するので、QUALITY_TIME_LAPSE_480PをQUALITY_480Pなどの他のサポートされている通常のプロファイルに削除した後でビデオをチェックするか、ビデオサイズなどを設定して純粋なカスタムメディアレコーダー設定を行います。時間経過が暗黙的に1倍ではないので

+0

あなたの答えをありがとう!実際にサポートされているフレームレートを確認する必要がありますが、30fpsはGalaxy Nexus S3の許容範囲内であることが確認されていますので、これは問題ではありません。 – spitzanator

関連する問題