Ho un video di registrazione MediaRecorder e sono molto confuso dall'effetto di setCaptureRate().MediaRecorder Android setCaptureRate() e velocità di riproduzione video
In particolare, mi preparo il mio MediaRecorder come segue:
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();
I record per cinque secondi (con un CountDownTimer, ma questo è irrilevante), e questo è il file che viene generato:
$ 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
Si noti che la durata è di circa 3 secondi. Il video funziona anche molto più velocemente, come se fossero 5 secondi di video stipati in 3.
Ora, se registro preparando il mio mediaRecorder esattamente come sopra, ma sottraendo la linea setCaptureRate (30f), ottengo un file come this:
$ 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
Si noti che la Durata è come previsto, circa 5 secondi. Anche il video viene riprodotto a una velocità normale.
Sto usando setCaptureRate (30f) perché 30 fotogrammi al secondo è il valore del mio CamcorderProfile's videoFrameRate. Sul mio Galaxy Nexus S2 (4.2.1), omettendo setCaptureRate() va bene, ma quando ho provato su un Galaxy Nexus S3 (4.1.1), omettendo setCaptureRate() si ottiene l'utile errore "start failed -22" quando ho chiamato mMediaRecorder.start()
.
Quindi, cosa mi manca? Ho pensato che la velocità di acquisizione e il frame rate del video fossero indipendenti, ma è chiaro che non lo sono. C'è un modo per determinare a livello di codice ciò di cui ho bisogno per impostare la velocità di acquisizione al fine di determinare che il mio video riproduce a velocità 1x?
Perché 'QUALITY_TIME_LAPSE_480P' e non' QUALITY_480P'? Il tempo trascorso non è intrinsecamente una velocità di riproduzione 1x. –
Hai anche esaminato 'MediaRecorder.setVideoFrameRate'? –
@RomanNurik Grazie per il tuo commento! In realtà non voglio registrare il suono, e l'unico modo per farlo sembra essere usando un video time lapse. Re: setVideoFrameRate, viene chiamato quando chiamo setProfile(): https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaRecorder.java#L329 Infatti, guardando la fonte è ciò che mi ha dato la mancia per aver bisogno di chiamare setCaptureRate() in primo luogo. https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaRecorder.java#L337 Altrimenti, ho ottenuto un -22. – spitzanator