[iOS]短視頻錄制(新)

簡單介紹

2020/04 已重構(gòu) 支持cocoapod

這篇文章是自己做短視頻功能這幾個(gè)月的一個(gè)總結(jié),以下文字或代碼有任何不妥的地方希望各位積極指出錯(cuò)誤,并給出建議。

從短視頻拍攝基本功能來說,我想應(yīng)該有以下,美顏磅网,水印,斷點(diǎn)拍攝筷屡,編輯功能涧偷,編輯功能包含,濾鏡添加毙死,背景音樂添加燎潮,貼圖貼紙?zhí)砑樱哔|(zhì)量壓縮(視頻降低碼率)扼倘。針對這些功能跟啤,我會(huì)逐一介紹其實(shí)現(xiàn)方法。

使用到的第三方庫:TZImagePickerController,GPUImage隅肥,SDAVAssetExportSession

demo效果圖

文章末尾會(huì)附上demo地址

預(yù)覽畫面支持美顏切換竿奏,前后相機(jī)切換


5711487-e5b15cbaac9fd2ef.PNG

錄制中


5711487-b8918b5001fef0f4.PNG

暫停錄制,支持?jǐn)帱c(diǎn)回刪


5711487-499df69972480db7.PNG

濾鏡選擇共8重


5711487-b307e065acbd0435.PNG

選擇音樂


5711487-93f479e492d36d8f.PNG

貼紙選擇腥放,可隨意調(diào)整貼紙位置


5711487-61cc436cb1264c29.PNG

預(yù)覽發(fā)布頁面泛啸,按各自實(shí)際app需求調(diào)整


5711487-5839bcfb739bf35d.PNG

錄制功能實(shí)現(xiàn)

錄制功能是基于GPUImageVideoCamera實(shí)現(xiàn)的:

相機(jī)初始化

videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset1280x720 cameraPosition:AVCaptureDevicePositionBack];

給相機(jī)添加濾鏡

filter = [[LFGPUImageEmptyFilter alloc] init];  //這個(gè)濾鏡是一個(gè)空濾鏡

filteredVideoView = [[GPUImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; //創(chuàng)建預(yù)覽畫面

[videoCamera addTarget:filter];

[filter addTarget:filteredVideoView];

開起預(yù)覽

[videoCamera startCameraCapture];  //啟動(dòng)相機(jī)

切換至美顏濾鏡

[videoCamera removeAllTargets]; //移除其它濾鏡

filter = [[GPUImageBeautifyFilter alloc] init];//美顏濾鏡

[videoCamera addTarget:filter];

[filter addTarget:filteredVideoView];

視頻錄制以及斷點(diǎn)續(xù)拍

斷點(diǎn)續(xù)拍的實(shí)質(zhì)就是把多個(gè)視頻合并成同一視頻

開始錄制

movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(720.0, 1280.0)];

movieWriter.isNeedBreakAudioWhiter = YES;

movieWriter.encodingLiveVideo = YES;

movieWriter.shouldPassthroughAudio = YES;

[filter addTarget:movieWriter];

videoCamera.audioEncodingTarget = movieWriter;

[movieWriter startRecording];

暫停錄制

暫停錄制就是把視頻先保存起來,并將視頻地址保存在數(shù)組中秃症,這樣就能實(shí)現(xiàn)斷點(diǎn)續(xù)拍候址。

[movieWriter finishRecording];

[filter removeTarget:movieWriter];

[urlArray addObject:[NSURL URLWithString:[NSString stringWithFormat:@"file://%@",pathToMovie]]];

拍攝完成后的合成操作以及水印添加

創(chuàng)建音視頻合成體,以及視頻通道容器种柑,音頻通道容器

[[AVMutableComposition alloc] init];

[mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio

preferredTrackID:kCMPersistentTrackID_Invalid];

[mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo

preferredTrackID:kCMPersistentTrackID_Invalid];

用AVAsset取出素材岗仑,并且分別取出音頻軌道 與視頻軌道按時(shí)間措添加至 上面創(chuàng)建的音視頻容器中

AVAsset* asset = [AVURLAsset URLAssetWithURL:videosPathArray[i] options:options];

//獲取AVAsset中的音頻 或者視頻

AVAssetTrack *assetAudioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] firstObject];

//向通道內(nèi)加入音頻或者視頻

BOOL ba = [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)

ofTrack:assetAudioTrack

atTime:totalDuration

error:&erroraudio];

//向通道內(nèi)加入視頻步驟與上面音頻的添加差不多

視頻水印的添加,創(chuàng)建layer 聚请,并將layer 添加AVMutableVideoComposition 這個(gè)對象中

視頻導(dǎo)出荠雕,創(chuàng)建AVAssetExportSession 對象 ,并為其設(shè)置videoComposition屬性驶赏,以此添加水印

//視頻導(dǎo)出工具

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition

presetName:AVAssetExportPreset1280x720];

exporter.videoComposition = videoComp;

導(dǎo)出方法 - (void)exportAsynchronouslyWithCompletionHandler:(void (^)(void))handler;

導(dǎo)出成功后進(jìn)入下一個(gè)視頻編輯頁面

視頻濾鏡處理

創(chuàng)建視頻預(yù)覽炸卑,使用GPUImageMovie工具 并結(jié)合avPlayer

mainPlayer = [[AVPlayer alloc] init];

playerItem = [[AVPlayerItem alloc] initWithURL:videoURL];

[mainPlayer replaceCurrentItemWithPlayerItem:playerItem];

playerLayer = [AVPlayerLayer playerLayerWithPlayer:mainPlayer];

movieFile = [[GPUImageMovie alloc] initWithPlayerItem:playerItem];

movieFile.runBenchmark = YES; movieFile.playAtActualSpeed = YES;

//新建一個(gè)空白濾鏡添加至 movieFile

filter = [[LFGPUImageEmptyFilter alloc] init];

_filtClassName = @"LFGPUImageEmptyFilter";

[movieFile addTarget:filter];

//視頻預(yù)覽容器view

_filterView = [[GPUImageView alloc] initWithFrame:self.view.bounds];

[self.view addSubview:_filterView];

[filter addTarget:_filterView];

開始預(yù)覽方法:- (void)startProcessing;

//avplay開始播放

[mainPlayer play];

[movieFile startProcessing];

切換濾鏡效果

[movieFile removeAllTargets];

//新建一個(gè)新的濾鏡文件

filter = [[NSClassFromString(_filtClassName) alloc] init];

//將濾鏡添加至 movieFile上

[movieFile addTarget:filter];

//重新添加預(yù)覽容器view

[filter addTarget:_filterView];

生成帶濾鏡處理后的視頻

//1.新建用于導(dǎo)出的MovieFile

endMovieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];

endMovieFile.runBenchmark = YES;

endMovieFile.playAtActualSpeed = NO;

//2.給MovieFile添加濾鏡

endFilter = [[NSClassFromString(_filtClassName) alloc] init];

[endMovieFile addTarget:endFilter];

//3.新建GPUImageMovieWriter寫入類

movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(720.0, 1280.0)];

[endFilter  addTarget:movieWriter];

movieWriter.shouldPassthroughAudio = YES;

endMovieFile.audioEncodingTarget = movieWriter;

[endMovieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];

//4.開始寫入

[movieWriter startRecording];

[endMovieFile startProcessing];

[movieWriter setCompletionBlock:^{

//.完成后的邏輯處理

}];

音樂合成處理/貼圖合成處理

此處方法原理 與第一頁視頻合成,水印處理基本相同煤傍。前者就是將音頻素材 添加到音頻軌道中盖文, 后者還是視頻layer上加layer;

視頻的壓縮處理

NSDictionary* options = @{AVURLAssetPreferPreciseDurationAndTimingKey:@YES};

AVAsset* asset = [AVURLAsset URLAssetWithURL:inputVideoUrl options:options];

NSArray* keys = @[@"tracks",@"duration",@"commonMetadata"];

[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{

SDAVAssetExportSession *compressionEncoder = [SDAVAssetExportSession.alloc initWithAsset:asset]; // provide inputVideo Url Here

compressionEncoder.outputFileType = AVFileTypeMPEG4;//文件輸出格式

compressionEncoder.outputURL = outputVideoUrl; //文件輸出地址

//視頻參數(shù)配置

compressionEncoder.videoSettings = @

{

AVVideoCodecKey: AVVideoCodecH264,//編碼方式

AVVideoWidthKey: @720,  //視頻寬

AVVideoHeightKey: @1280,  //視頻高

AVVideoCompressionPropertiesKey: @

{

//2000*1000  建議800*1000-5000*1000

//            AVVideoAverageBitRateKey: @2500000, // Give your bitrate here for lower size give low values

AVVideoAverageBitRateKey: _bit,//比特lv

AVVideoProfileLevelKey: AVVideoProfileLevelH264HighAutoLevel,

AVVideoAverageNonDroppableFrameRateKey: _frameRate,//fps

},

};

//音頻參數(shù)配置

compressionEncoder.audioSettings = @

{

AVFormatIDKey: @(kAudioFormatMPEG4AAC),//編碼方式

AVNumberOfChannelsKey: @2,//通道蚯姆,雙通道

AVSampleRateKey: @44100,//菜樣率

AVEncoderBitRateKey: @128000,//編碼比特lv

};

[compressionEncoder exportAsynchronouslyWithCompletionHandler:^

{

//處理成功

}];

}];

Demo傳送門:https://github.com/doubleYang1020/DYVideoCamera

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末五续,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子龄恋,更是在濱河造成了極大的恐慌疙驾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篙挽,死亡現(xiàn)場離奇詭異荆萤,居然都是意外死亡镊靴,警方通過查閱死者的電腦和手機(jī)铣卡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偏竟,“玉大人煮落,你說我怎么就攤上這事∮荒保” “怎么了蝉仇?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我轿衔,道長沉迹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任害驹,我火速辦了婚禮鞭呕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宛官。我一直安慰自己葫松,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布底洗。 她就那樣靜靜地躺著腋么,像睡著了一般。 火紅的嫁衣襯著肌膚如雪亥揖。 梳的紋絲不亂的頭發(fā)上珊擂,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音徐块,去河邊找鬼未玻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛胡控,可吹牛的內(nèi)容都是我干的扳剿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼昼激,長吁一口氣:“原來是場噩夢啊……” “哼庇绽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起橙困,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤瞧掺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后凡傅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辟狈,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年夏跷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哼转。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡槽华,死狀恐怖壹蔓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情猫态,我是刑警寧澤佣蓉,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布披摄,位于F島的核電站,受9級特大地震影響勇凭,放射性物質(zhì)發(fā)生泄漏疚膊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一虾标、第九天 我趴在偏房一處隱蔽的房頂上張望酿联。 院中可真熱鬧,春花似錦夺巩、人聲如沸贞让。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喳张。三九已至,卻和暖如春美澳,著一層夾襖步出監(jiān)牢的瞬間销部,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工制跟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舅桩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓雨膨,卻偏偏與公主長得像擂涛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子聊记,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容