SCRecorder錄制視頻導(dǎo)出時(shí)間過(guò)長(zhǎng)的優(yōu)化
IOS視頻錄制 AVFoundation SCRecorder[1]
遇到問(wèn)題
在項(xiàng)目中需要錄制視頻,為圖方便使用SCRecorder第三方庫(kù)進(jìn)行開發(fā)驱富,誰(shuí)知遇到的坑還是挺多锚赤,在保存視頻的時(shí)候遇到導(dǎo)出視頻時(shí)間過(guò)長(zhǎng)的問(wèn)題,錄制完成后還需要導(dǎo)出視頻,估計(jì)在導(dǎo)出時(shí)做了視頻轉(zhuǎn)碼和壓縮等工作褐鸥,10分鐘視頻要等個(gè)1分鐘實(shí)在讓人抓狂线脚,代碼如下:
// Merge all the segments into one file using an AVAssetExportSession
[recordSession mergeSegmentsUsingPreset:AVAssetExportPresetHighestQuality completionHandler:^(NSURL *url, NSError *error) {
if (error == nil) {
// Easily save to camera roll
[url saveToCameraRollWithCompletion:^(NSString *path, NSError *saveError) {
}];
} else {
NSLog(@"Bad things happened: %@", error);
}
}];
解決方案1——使用系統(tǒng)框架AVFoundation
放棄使用SCRecorder,使用IOS系統(tǒng)的AVFoundation叫榕,AVCaptureSession[2]和AVCaptureMovieFileOutput[3]可以很方便的錄制出MP4文件浑侥。這種方式在百度上很容易找到,這里不再詳述晰绎。
優(yōu)勢(shì):
高度訂制寓落,SCRecorder也是基于AVFoundation實(shí)現(xiàn)的。劣勢(shì):
配置AVCaptureSession過(guò)于麻煩荞下,對(duì)于切換攝像頭和閃光燈開關(guān)等設(shè)置不太方便伶选。還有就是已經(jīng)入了SCRecorder的坑,改用AVFoundation來(lái)實(shí)現(xiàn)有點(diǎn)過(guò)于麻煩
解決方案2——啟用SCRecorder的fastRecordMethodEnabled屬性
在查看SCRecorder的文檔時(shí)發(fā)現(xiàn)一個(gè)fastRecordMethodEnabled屬性锄弱,文檔內(nèi)容如下:
Whether the fast recording method should be enabled.
Enabling this will disallow pretty much every features provided
by SCVideoConfiguration and SCAudioConfiguration. It will internally
uses a AVCaptureMovieFileOutput that provides no settings. If you have
some performance issue, you can try enabling this.
Default is NO.
(注:本人英文半瓶子水在這里就不翻譯了,自行度娘)
配置代碼:
SCRecorder *recorder = [SCRecorder recorder];
[recorder startRunning]
recorder.session = [SCRecordSession recordSession];
recorder.fastRecordMethodEnabled = YES;
[recorder record];
然后結(jié)束錄制后在SCRecorderDelegate的- (void)recorder:(SCRecorder *__nonnull)recorder didCompleteSession:(SCRecordSession *__nonnull)session;
中就可以拿到錄制好的視頻了考蕾,session中有一個(gè)只讀的outputUrl
屬性就是了
有一個(gè)缺點(diǎn)就是路徑還是TM不能自己指定,蛋疼会宪。
后來(lái)研究了下他的源代碼肖卧,可以看到SCRecorder.m里面的定義如下:
AVCaptureVideoPreviewLayer *_previewLayer;
AVCaptureSession *_captureSession;
UIView *_previewView;
AVCaptureVideoDataOutput *_videoOutput;
AVCaptureMovieFileOutput *_movieOutput;
AVCaptureAudioDataOutput *_audioOutput;
AVCaptureStillImageOutput *_photoOutput;
可以看到里面有一個(gè)_movieOutput的屬性,只要拿到他我們就可以為所欲為啦:(OC動(dòng)態(tài)運(yùn)行機(jī)制閃亮登場(chǎng))
let movieFileOutput = recorder?.value(forKeyPath: "_movieOutput")
后續(xù)可以使用movieFileOutput來(lái)指定存儲(chǔ)路徑啦5Ф臁塞帐!
注:提取_movieOutput的方案沒(méi)有親身實(shí)踐過(guò)拦赠,不知道是否可行!
解決方案3——替換SCRecorder的AVCaptureMovieFileOutput
創(chuàng)建一個(gè)AVCaptureMovieFileOutput然后add到Recorder的AVCatureSession上經(jīng)行錄制,不需要再調(diào)用Recorder的record方法葵姥,但是需要調(diào)用Recorder的startRunning方法荷鼠。不然catureSession的值會(huì)是nil。
直接貼代碼
let movieOutput = AVCaptureMovieFileOutput()
recorder?.captureSession?.addOutput(movieOutput)
movieOutput.startRecording(toOutputFileURL: self.outputUrl, recordingDelegate: self)
so easy榔幸!
第一次寫技術(shù)文檔允乐,有什么疏漏或者不正確的地方還請(qǐng)指出,互相學(xué)習(xí)削咆。
2016年12月16日更新
目前本人已經(jīng)棄用SCRecoder牍疏,改用AVFoundation框架來(lái)實(shí)現(xiàn)錄制視頻功能,直接放出代碼:
github地址
-
GitHub: SCRecorder ?
-
Apple官方文檔:AVCaptureSession ?
-
Apple官方文檔:MovieFileOutpu ?