這是一篇關於慢動做錄像(slowmotion)的文章,看完後相信你對慢動做錄像不會再感到陌生了~html
這篇文章針對下面幾點來展開: 1)寫這篇文章的起因? 2)什麼是慢動做錄像(SlowMotionRecord)? 3)Android上如何實現慢動做錄像? 4)調試demo下載地址? 5)調試遇到的問題及解決?java
2月份的時候,在一個音視頻開發的學習交流羣裏,有位網友問到**"Android相機有啥設置能夠作到slow motion?"**,我認真的想了下,而後又簡單看了下高通的曉龍相機源碼,大概知道是怎麼實現後,給了下思路。android
後面我還一直在想這個事情,覺的本身給的思路太簡單了,有時間仍是得再研究研究,本身得敲下代碼跑通下才好,因而就有了這篇文章。git
一般咱們人眼可以接受的最好的視頻幀速率是24幀/每秒左右。那若是咱們用120幀/秒拍攝一個動做,再用24幀每秒來播放的話,視頻就放慢了5倍,這個就是慢動做錄像了。github
慢動做錄像,又叫高幀率錄像(HFR),也就是以高fps(運行速率)捕獲、編碼並保存爲30 fps(目標速率),這種狀況運行速率大於目標速率。api
(還有一種模式叫作高速錄製(HSR) : 即以高fps(運行速率)捕獲、編碼並保存爲高 fps(目標速率),運行速率等於目標速率。)微信
這篇文章只介紹慢動做錄像。(調試環境基於高通曉龍865芯片 Android9.0)session
有了上面關於慢動做的概念後,那在Android上如何用代碼來實現呢?說到錄像,那咱們應該要想到MediaRecorder了。慢動做,也就是高幀率錄像,那確定得調用mediaRecorder設置高幀率了。ide
好了,咱們還得再有一個概念,數據是從攝像頭sensor出來的,那咱們須要120fps,總得攝像頭支持才行吧。因此呢,就有一個先決條件了,硬件得支持才行,下面會講如何查詢當前硬件是否支持。學習
假設硬件支持的狀況下,咱們來看下軟件上應用的調用狀況。一、新類CameraConstrainedHighSpeedCaptureSession查看Android的開發文檔,咱們能夠看到,從Android 6.0開始,Camera相關的,添加了一個新的類CameraConstrainedHighSpeedCaptureSession,從描述上看,咱們就能夠知道,這個是專門爲高速、高幀率錄像準備的。換一句話說,也就是Android 6.0以上,Android自己才支持這個高速、高幀率錄像。(我在本身早年用的nubiya手機上看了下,Android 5.1的系統,系統相機也帶了慢動做功能,不過它這個慢動做應該是廠家本身定製開發的,那會Android還沒提供相關接口)
二、查詢當前硬件是否支持高幀率錄像經過CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS來獲取available size。若是存在available,則判斷爲支持。
public static boolean hasHighSpeedVideoConfigs(Context context, String cameraId) { try { CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId); HighSpeedVideoConfiguration[] highSpeedVideoConfigs = characteristics.get( CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS); return highSpeedVideoConfigs != null && highSpeedVideoConfigs.length > 0; } catch (Exception e) { } return false; }複製代碼
三、獲取支持的高幀率錄像videoSize從map.getHighSpeedVideoSizes()中獲取支持的videoSize,而後選擇個合適的size,注意這裏的previewSize須要和videoSize保持一致。
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); StreamConfigurationMap map = characteristics .get(SCALER_STREAM_CONFIGURATION_MAP); mVideoSize = chooseVideoSize(map.getHighSpeedVideoSizes()); mPreviewSize = mVideoSize;//這裏須要保持previewSize 和videoSize一致複製代碼
四、CONTROL_AE_TARGET_FPS_RANGE設置爲高幀率範圍(120,120)
Range aeFps = new Range(120, 120); mPreviewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, aeFps);複製代碼
五、建立session採用createConstrainedHighSpeedCaptureSession高幀率錄像建立session,使用專門提供的api接口。
// Start a capture session mCameraDevice.createConstrainedHighSpeedCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { ...... } @Override public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { ...... } }, mBackgroundHandler);複製代碼
六、採用setRepeatingBurstsession configure成功後,調用setRepeatingBurst不停的request,這個和正常模式有點區別,正常模式是調用的setRepeatingRequest。
CaptureRequest request = mPreviewBuilder.build(); List<CaptureRequest> slowMoRequests = ((CameraConstrainedHighSpeedCaptureSession) mPreviewSession) .createHighSpeedRequestList(request); mPreviewSession.setRepeatingBurst(slowMoRequests, null, mBackgroundHandler);複製代碼
七、MediaRecorder相關參數設置爲對應的高幀率參數相對應的,mediaRecorder的一些參數也須要設置爲高幀率參數。
mProfile = getProfile(); int bitRate = getHighSpeedVideoEncoderBitRate(mProfile, mProfile.videoFrameRate, VEDIO_HIGH_SPEED_FRAME_RATE); mMediaRecorder.setVideoEncodingBitRate(bitRate); mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); mMediaRecorder.setCaptureRate(VEDIO_HIGH_SPEED_FRAME_RATE);複製代碼
原本想着上傳到github的,奈何github不給力,訪問不了。先上傳到百度網盤先,須要的能夠自行下載參考。(關注"小馳筆記",回覆"慢動做錄像"便可獲取代碼下載地址)
》》》》問題1:
Process: com.xcbj.camera, PID: 21818 java.lang.IllegalArgumentException: Surface size 1440x1080 is not part of the high speed supported size list [1280x720, 720x480, 640x480, 1920x1080] at android.hardware.camera2.utils.SurfaceUtils.checkConstrainedHighSpeedSurfaces(SurfaceUtils.java:193) at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSessionInternal(CameraDeviceImpl.java:881) at android.hardware.camera2.impl.CameraDeviceImpl.createConstrainedHighSpeedCaptureSession(CameraDeviceImpl.java:627)複製代碼
[分析]
》》》》問題2: Fps rang[30,30] in the request is not a supported hight speed fps range...
Process: com.xcbj.camera, PID: 27138 java.lang.IllegalArgumentException: Fps range [30, 30] in the request is not a supported high speed fps range [[120, 120], [240, 240], [480, 480], [30, 120], [30, 240], [30, 480]] at android.hardware.camera2.utils.SurfaceUtils.checkConstrainedHighSpeedSurfaces(SurfaceUtils.java:180) at android.hardware.camera2.impl.CameraConstrainedHighSpeedCaptureSessionImpl.createHighSpeedRequestList(CameraConstrainedHighSpeedCaptureSessionImpl.java:89)複製代碼
[分析]
*本人從事Android Camera相關開發已有5年,
*目前在深圳上班,
*歡迎關注個人微信公衆號"小馳筆記"
*但願和更多的小夥伴一塊兒交流 ~
-------- 2021.03.25 深圳 00:53·