本文分為以下幾個步驟:
*1.數(shù)據(jù)采集
*2.配置相關參數(shù)
*3.準備開始編碼
*4.編碼完成
*5.拼接H264文件
*6.寫入文件
*7.停止捕捉
首先,給相關的類配置相關的對象:
*捕捉會話:AVCaptureSession
*捕捉設備輸入:AVCaptureDeviceInput
*捕捉預覽:AVCaptureVideoPreviewLayer
*捕捉設備輸出:AVCaptureVideoDataOutput
*編碼會話對象:VTCompressionSessionRef

第一步:數(shù)據(jù)采集



第二步:配置VideoToolbox的相關參數(shù)
/*
參數(shù)2、參數(shù)3:設置寬、高
參數(shù)4:設置編碼類型
參數(shù)8:編碼完成后的回到函數(shù),
參數(shù)9:self,需要橋接當前的對象過去
參數(shù)10:指定的sEncodeingSession地址。
*/
1.創(chuàng)建VideoToolBox中的Session:VTCompressionSessionCreate();
2.設置相關屬性配置:VTSessionSetProperty
3.開始編碼:VTCompressionSessionPrepareToEncodeFrames


第三步:對采集到的數(shù)據(jù)進行編碼,采集到的數(shù)據(jù),經(jīng)過協(xié)議協(xié)議方法中的CMSampleBufferRef封裝著數(shù)據(jù)。這個協(xié)議方法,無論是采集到的是音頻還是視頻,都會回到這個函數(shù),對音視頻的編碼,可以根據(jù)AVCaptureOutput 這個對象是AVCaptureAudioDataOutput 還是AVCaptureVideoDataOutput來判斷是音頻還是視頻。
協(xié)議方法:-(void)captureOutput:(AVCaptureOutput*)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
第四步,對采集到的數(shù)據(jù)進行編碼,先從CMSampleBufferRef中獲取視頻幀,獲取相對應的幀時間frameID,然后構建編碼函數(shù)。
參數(shù)類型:
?參數(shù)1;encodesession
?參數(shù)2;未編碼的數(shù)據(jù)
?參數(shù)3;時間戳
? 參數(shù)4;幀展示時間,如果沒有時間信息,kCMTimeInvalid
? 參數(shù)5;幀屬性 NULL
? 參數(shù)6;回調? 編碼過程回調 NULL
? 參數(shù)7;flags 同步還是異步
編碼函數(shù):VTCompressionSessionEncodeFrame()

第五步:編碼完成之后,會進行一個回到函數(shù),這個函數(shù)是自己自定義的,是使用C語言的方法來回調,函數(shù)涉及到的具體參數(shù),可以通過創(chuàng)建sEncodeingSession時,點擊相關的參數(shù)進去查看參考。在這個回調函數(shù)當中,分為以下幾步:
回調函數(shù):
voidDidCompressH264(void*outputCallbackRefCon,void*sourceFrameRefCon,OSStatusstatus,VTEncodeInfoFlagsinfoFlags,CMSampleBufferRefsamplebuffer)
1;判斷返回的狀態(tài)以及數(shù)據(jù)有沒有準備好,沒有則返回。
2:在C語言函數(shù)當中,獲取當前的對象,將當前對象進行橋接。
3:判斷是否為關鍵幀,如果是關鍵幀,就獲取sps和pps,然后寫入H264文件,獲取sps和pps的時候,需要獲取到相對應ppsSize,ppsContent以及ppsCount,sps同理。
4:獲取NALU數(shù)據(jù),在這個NALU獲取數(shù)據(jù)時候,需要進行大小端切換,然后在寫入H264文件。



第六步: 寫入數(shù)據(jù),將編碼后獲取到的sps和pps寫入數(shù)據(jù),以及將NALU數(shù)據(jù)寫入數(shù)據(jù),在將這些數(shù)據(jù)寫入之前,要先寫入他們的起始位0001。


第七步:完成捕捉。
使用的函數(shù):VTCompressionSessionCompleteFrames()
