Camera2、MediaCodec錄制mp4

PS:做想做的事,每天至少做一點(diǎn),不求做多少,慢慢改變。
Camera2的使用
MediaCodec輸入方式
MediaCodec編碼Camera2數(shù)據(jù)
錄制流程
錄制效果
Camera2的使用

MediaCodec的輸入方式
Surface:使用 Surface 作為編碼器 MediaCodec 的輸入,即將 MediaCodec 創(chuàng)建的 Surface 作為其輸入,這個 Surface 由 MediaCodec 的 createInputSurface 方法創(chuàng)建,當(dāng)相機(jī)將會將有效數(shù)據(jù)渲染到該 Surface 中,MediaCodec 就可以直接輸出編碼后的數(shù)據(jù)了。
InputBuffer:使用輸入緩沖區(qū)作為編碼器 MediaCodec 的輸入,這里需要填充的數(shù)據(jù)就是原始幀數(shù)據(jù),對應(yīng) Camera2 來說可直接通過 ImageReader 來進(jìn)行幀數(shù)據(jù)的獲取,獲取到的 Image 包含了寬度、高度、格式、時間戳及 YUV 數(shù)據(jù)分量等信息,可控程度更高。
MediaCodec編碼Camera2數(shù)據(jù)
1//?返回已成功編碼的輸出緩沖區(qū)的索引
2var?outputBufferId:?Int?=?mMediaCodec.dequeueOutputBuffer(bufferInfo,?0)
3if?(outputBufferId?==?MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)?{
4????//?添加視頻軌道
5????mTrackIndex?=?mMediaMuxer.addTrack(mMediaCodec.outputFormat)
6????mMediaMuxer.start()
7????mStartMuxer?=?true
8}?else?{
9????while?(outputBufferId?>=?0)?{
10????????if?(!mStartMuxer)?{
11????????????Log.i(TAG,?"MediaMuxer?not?start")
12????????????continue
13????????}
14????????//?獲取有效數(shù)據(jù)
15????????val?outputBuffer?=?mMediaCodec.getOutputBuffer(outputBufferId)??:?continue
16????????outputBuffer.position(bufferInfo.offset)
17????????outputBuffer.limit(bufferInfo.offset?+?bufferInfo.size)
18????????if?(pts?==?0L)?{
19????????????pts?=?bufferInfo.presentationTimeUs
20????????}
21????????bufferInfo.presentationTimeUs?=?bufferInfo.presentationTimeUs?-?pts
22????????//?將數(shù)據(jù)寫入復(fù)用器以生成文件
23????????mMediaMuxer.writeSampleData(mTrackIndex,?outputBuffer,?bufferInfo)
24????????Log.d(
25????????????TAG,
26????????????"pts?=?${bufferInfo.presentationTimeUs?/?1000000.0f}?s?,${pts?/?1000}?ms"
27????????)
28????????mMediaCodec.releaseOutputBuffer(outputBufferId,?false)
29????????outputBufferId?=?mMediaCodec.dequeueOutputBuffer(bufferInfo,?0)
30????}
31}
錄制流程
1//?配置狀態(tài)
2mMediaCodec.configure(mediaFormat,?null,?null,?MediaCodec.CONFIGURE_FLAG_ENCODE)
3//?創(chuàng)建Surface作為MediaCodec的輸入,createInputSurface只能在configure與start之間調(diào)用創(chuàng)建Surface
4mSurface?=?mMediaCodec.createInputSurface()
5//?start?...
1//?創(chuàng)建CaptureSession
2@RequiresApi(Build.VERSION_CODES.P)
3private?suspend?fun?createCaptureSession():?CameraCaptureSession?=?suspendCoroutine?{?cont?->
4????val?outputs?=?mutableListOf()
5????//?預(yù)覽Surface??????????????????????????????????????????????????????????????????????????????
6????outputs.add(OutputConfiguration(mSurface))
7????//?添加MediaCodec用作輸入的Surface???????????????????????????????????????????????????????????????????????????????
8????outputs.add(OutputConfiguration(EncodeManager.getSurface()))
9????val?sessionConfiguration?=?SessionConfiguration(
10????????SessionConfiguration.SESSION_REGULAR,
11????????outputs,?mExecutor,?...)
12????mCameraDevice.createCaptureSession(sessionConfiguration)
13}
1//?添加預(yù)覽的Surface和生成Image的Surface
2mCaptureRequestBuild?=?mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
3val?sur?=?EncodeManager.getSurface()
4mCaptureRequestBuild.addTarget(sur)
5mCaptureRequestBuild.addTarget(mSurface)
6
7//?設(shè)置各種參數(shù)
8mCaptureRequestBuild.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE,?1)?//?視頻穩(wěn)定功能是否激活
9//?發(fā)送CaptureRequest
10mCameraCaptureSession.setRepeatingRequest(
11????mCaptureRequestBuild.build(),
12????null,
13????mCameraHandler
14)
15//?開始編碼
16EncodeManager.startEncode()
錄制效果

評論
圖片
表情
