iOS視頻錄制(AVFoundation自定義相機)

前言

最近剛做完一個直播類的項目,在視頻這塊也有一定研究,下面總結下。

過程

首先視頻項目一般要求定制化,用UIImagePickerController不符合需求,所以基本上都是用AVFoundation自定義相機,在網上一搜,還是查到比較多參考博文的,其中簡書上的這篇iOS-AVFoundation自定義相機詳解比較詳細(內含Demo),十分值得參考。

另外蘋果官方也提供了一個Demo蘋果官方Demo-RosyWriter,后來我對比過兩個Demo發現,其實簡書那篇的Demo也是參考蘋果官方的再深入研究,所以在開發過程中以這兩個Demo參考基本夠用了。

AVFoundation 中視頻相關類:

會話
AVCaptureSession
輸入
AVCaptureDeviceInput
輸出
AVCaptureConnection
AVCaptureConnection
AVCaptureVideoDataOutput
AVCaptureStillImageOutput
AVCaptureMovieFileOutput
文件寫入
AVAssetWriter
AVAssetWriterInput

自定義AVFoundation主要為以下5個步驟:

1.創建session(捕捉會話)
2.創建device input(捕捉設備輸入)
3.預覽view
4.創建capture output(捕捉的輸出)
5.拍照、錄視頻(元數據轉成圖片或文件)

詳細代碼就不說了,下面主要說下我做的過程中遇到的一下問題:

1.實時視頻流AVCaptureVideoDataOutput和系統視頻錄制功能AVCaptureMovieFileOutput沖突,不能同時使用。AVCaptureMovieFileOutput是把音頻和視頻合成并輸出一個完整的音視頻文件,代碼比較簡單,但定制化功能少;而AVCaptureVideoDataOutput需要配合AVCaptureAudioDataOutput使用,分別輸出音頻和視頻兩條軌道的數據,并用AVAssetWriter寫入,代碼比較復雜,但定制功能多,推薦使用

2.關于碼率
以上蘋果和簡書上的demo都是通過分辨率計算碼率,代碼如下:

//計算像素
int numPixels = dimensions.width * dimensions.height;
int bitsPerSecond;
NSLog( @"No video settings provided, using default settings" );
// Assume that lower-than-SD resolutions are intended for streaming, and use a lower bitrate
if ( numPixels < ( 640 * 480 ) ) {
    bitsPerPixel = 4.05; // This bitrate approximately matches the quality produced by AVCaptureSessionPresetMedium or Low.
}
else {
    bitsPerPixel = 10.1; // This bitrate approximately matches the quality produced by AVCaptureSessionPresetHigh.
}
//碼率        
bitsPerSecond = numPixels * bitsPerPixel;
        
NSDictionary *compressionProperties = @{ AVVideoAverageBitRateKey : @(bitsPerSecond), 
                                                 AVVideoExpectedSourceFrameRateKey : @(30),
                                                 AVVideoMaxKeyFrameIntervalKey : @(30) };

如想自定義碼率可在以上代碼處設置,另外奉上開發過程中找到的一篇關于碼率的文章視頻質量,分辨率以及碼率之間的關系

另外,關于視頻的壓縮,我還特意和微信的對比過,在網上搜到這篇文章Compress in iOS,我是參照以上這篇文章,把分辨率設為960*540,再調整碼率,使視頻文件大小與微信相仿。

3.關于切換攝像頭
用上面說到的Demo,切換攝像頭時,你會發現屏幕會黑一下,體驗效果很不好,改良如下:

//切換攝像頭之前,先停止session
 [_captureSession stopRunning];
//給攝像頭的切換添加翻轉動畫
CATransition *animation = [CATransition animation];
animation.duration = .5f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.type = @"oglFlip";
animation.subtype = kCATransitionFromLeft;//動畫翻轉方向
[self.previewLayer addAnimation:animation forKey:nil];
//接下來開始切換攝像頭
......

由于我也是在別人的Demo基礎上改的代碼,所以我自己就不貼上代碼,稍微研究下簡書和蘋果上的Demo,再結合自己的需求,相信很快就能做出來了。

結束

學習之路,與君共勉。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容