Mam nagrywanie wideo MediaRecorder i jestem bardzo zdezorientowany przez efekt setCaptureRate().Android MediaRecorder setCaptureRate() i prędkość odtwarzania wideo
Konkretnie, przygotowuję moje MediaRecorder następująco:
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 rekord na pięć sekund (z CountDownTimer, ale to bez znaczenia), a to jest plik, który zostaje wygenerowany:
$ 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
Należy pamiętać, że czas trwania wynosi około 3 sekundy. Obraz wideo jest również odtwarzany znacznie szybciej, tak jakby to było 5 sekund wideo wepchniętym w 3.
Teraz, jeśli nagrywam, przygotowując mój plik multimedialny dokładnie tak, jak powyżej, ale odejmując linię setCaptureRate (30f), otrzymuję plik taki jak to:
$ 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
Należy pamiętać, że czas trwania jest zgodny z oczekiwaniami, około 5 sekund. Film odtwarzany jest również z normalną prędkością.
Używam setCaptureRate (30f), ponieważ 30 klatek na sekundę jest wartością mojego CamcorderProfile videoFrameRate. Na moim Galaxy Nexus S2 (4.2.1) pomijanie setCaptureRate() jest w porządku, ale kiedy testowałem na Galaxy Nexus S3 (4.1.1), pomijanie setCaptureRate() skutkuje zawsze pomocnym błędem "start failed -22" kiedy zadzwoniłem pod numer mMediaRecorder.start()
.
Więc, czego mi brakuje? Pomyślałem, że współczynnik przechwytywania i szybkość klatek wideo są niezależne, ale jest jasne, że tak nie jest. Czy istnieje sposób, aby określić programowo, co muszę ustawić szybkość przechwytywania na w celu ustalenia, że moje wideo odtwarza z prędkością 1x?
Dlaczego 'QUALITY_TIME_LAPSE_480P', a nie' QUALITY_480P'? Przerwy w czasie nie są z natury 1 prędkością odtwarzania. –
Czy chciałeś również wywołać 'MediaRecorder.setVideoFrameRate'? –
@RomanNurik Dzięki za komentarz! Nie chcę nagrywać dźwięku, a jedynym sposobem na zrobienie tego wydaje się być użycie filmu poklatkowego. Odp: setVideoFrameRate, zostaje wywołana, gdy zadzwonię do setProfile(): https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaRecorder.java#L329 W rzeczywistości, patrząc na źródło jest to, co naprowadziło mnie do konieczności wywołania setCaptureRate() w pierwszej kolejności. https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaRecorder.java#L337 W przeciwnym razie dostałem -22. – spitzanator