視頻特效制作1
很多人覺得視頻這塊比較復(fù)雜,其實(shí)只是假象糠馆,視頻這塊不是復(fù)雜,而是套路多怎憋。
舉個(gè)例子,可能很多人想做個(gè)短視頻錄制又碌,能暫停錄制繼續(xù)錄制的那種九昧,興致勃勃的網(wǎng)上搜代碼,結(jié)果看到
CMFormatDescriptionRef fmt= CMSampleBufferGetFormatDescription(sampleBuffer);
這么一句毕匀,直接就跪了铸鹰。What the hell?
然后能抗住打擊的繼續(xù)往下看的人再看到這么一段皂岔。
if(CMSampleBufferDataIsReady(sampleBuffer)){if(_writer.status ==AVAssetWriterStatusUnknown)? ? {CMTimestartTime =CMSampleBufferGetPresentationTimeStamp(sampleBuffer);? ? ? ? [_writer startWriting];? ? ? ? [_writer startSessionAtSourceTime:startTime];? ? }if(_writer.status ==AVAssetWriterStatusFailed)? ? {NSLog(@"writer error %@", _writer.error.localizedDescription);returnNO;? ? }if(bVideo)? ? {if(_videoInput.readyForMoreMediaData ==YES)? ? ? ? {? ? ? ? ? ? [_videoInput appendSampleBuffer:sampleBuffer];returnYES;? ? ? ? }? ? }else{if(_audioInput.readyForMoreMediaData)? ? ? ? {? ? ? ? ? ? [_audioInput appendSampleBuffer:sampleBuffer];returnYES;? ? ? ? }? ? }}returnNO;
Command+W.(88)
上面的代碼主要意思是把CMSampleBuffer這個(gè)東西蹋笼,姑且叫圖像每一幀的基礎(chǔ)數(shù)據(jù),加入AvAssetWriter躁垛,然后AvAssetWriter以后可以把這一楨一幀的數(shù)據(jù)輸出成video剖毯。其實(shí)就是代碼看起來惡心一點(diǎn),但是流程一點(diǎn)不復(fù)雜教馆。但是今天不是講怎么錄制的逊谋,今天講視頻剪輯。(如果真的只是對(duì)短視頻錄制感興趣對(duì)視頻剪輯不感興趣的給你們推薦一個(gè)庫土铺,https://github.com/rFlex/SCRecorder)
有這方面需求的可以去搬運(yùn)胶滋。
今天不講技術(shù),主要講套路悲敷。套路如下
Putting It All Together: Combining Multiple Assets and Saving the Result to the Camera Roll
This brief code example illustrates how you can combine two video asset tracks and an audio asset track to create a single video file. It shows how to:
1.Create an AVMutableComposition object and add multiple AVMutableCompositionTrack objects
2.Add time ranges of AVAssetTrack objects to compatible composition tracks
3.Check the preferredTransform property of a video asset track to determine the video’s orientation
4.Use AVMutableVideoCompositionLayerInstruction objects to apply transforms to the video tracks within a composition
5.Set appropriate values for the renderSize and frameDuration properties of a video composition
Use a composition in conjunction with a video composition when exporting to a video file
6.Save a video file to the Camera Roll
這是我直接從官網(wǎng)拔下來的镀钓,基本上就是最正確的步驟了。我來解釋一下镀迂。
1.創(chuàng)建一個(gè)AVMutableComposition類,這個(gè)類是干嘛的呢唤蔗?如圖
Smaller icon
這個(gè)東西是用來添加AVMutableCompositionTrack的探遵,你可以把它想象成用來調(diào)度每個(gè)視頻次序,時(shí)間的這么一個(gè)調(diào)度器妓柜。
那么問題又來了箱季,AVMutableCompositionTrack這個(gè)玩意干嘛用的?
這個(gè)玩意其實(shí)是用來加載視頻的一個(gè)容器棍掐。
我來貼段代碼
mixComposition = [[AVMutableCompositionalloc] init];// create first trackAVMutableCompositionTrack*firstTrack =? ? [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideopreferredTrackID:kCMPersistentTrackID_Invalid];? ? [firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, firstAsset.duration)? ? ? ? ? ? ? ? ? ? ? ? ofTrack:[[firstAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]? ? ? ? ? ? ? ? ? ? ? ? atTime:kCMTimeZero? ? ? ? ? ? ? ? ? ? ? ? ? error:nil];
第一句藏雏,初始化AVMutableComposition,相信這段都看得懂作煌,第二句掘殴,創(chuàng)建AVMutableCompositionTrack,這句有點(diǎn)奇怪粟誓,其實(shí)意思就是用mixComposition創(chuàng)建一個(gè)AVMutableCompositionTrack奏寨,而且這個(gè)東西是存video類型的,那當(dāng)然你可以把后面的參數(shù)改成addMutableTrackWithMediaType:AVMediaTypeAudio的鹰服,那就可以存音軌了病瞳。
然后呢揽咕,你想想,你要剪輯視頻套菜,你是不是得規(guī)定剪輯之后視頻的時(shí)長亲善,視頻的起始時(shí)間,沒問題吧逗柴。那么最后一句的insertTimeRange就是安排firstTrack的時(shí)長蛹头,那我們不縮短,就按照這個(gè)firstAsset的時(shí)長來嚎于,從kctimerzero(就是從0秒開始)掘而,到這個(gè)firstAsset.duration(就是這個(gè)視頻的總時(shí)長),firstAsset是個(gè)什么東西我后面說于购。ofTrack這個(gè)東西就是我們的視頻來源袍睡。
為什么要規(guī)定MediaType呢?因?yàn)槟闩牡囊欢我曨l肋僧,包括video和audio斑胜,也就是視頻和音頻啊,我們這段只要視頻就行了嫌吠,所以type是video止潘。
atTime:這個(gè)參數(shù)是干嘛的呢?就是規(guī)定我們這段視頻在合并之后放在第幾秒辫诅?那我們就放在第0秒好了凭戴。
那個(gè)firstAsset是什么,我再貼段代碼炕矮。
AVURLAsset *firstAsset;firstAsset = [AVAsset assetWithURL:videoURL];
videoURL,是你的相冊(cè)里面你拍的video的地址么夫,然后我們用AVURLAsset這個(gè)類取到video的信息。不懂得自行百度肤视。
然后第二個(gè)依樣畫葫蘆就行了档痪。不贅述(我提供的DEMO里有,你們自行下載)邢滑。
但是還有一個(gè)重要的點(diǎn)腐螟,比如你要合并視頻,那么第二個(gè)視頻要放在第一個(gè)視頻后面對(duì)吧困后,所以你第二個(gè)asset的atTime參數(shù)就不能設(shè)置為KCMTimeZero了乐纸,而是要firstAsset.duration了.那么你想讓第一個(gè)和第二個(gè)同時(shí)播,那自然可以摇予,兩個(gè)的insertTime都是kcmtimezero就行了锯仪。
然后重頭戲來了。就是這個(gè)叫做AVMutableVideoCompositionLayerInstruction的東西趾盐,它的主要作用是用來規(guī)定video的樣式庶喜,比如說小腊,你合并兩個(gè)視頻,第一個(gè)怎么放久窟?轉(zhuǎn)九十度放呢秩冈,還是邊放邊旋轉(zhuǎn)呢?還是邊放邊改變透明度斥扛?都是由這個(gè)掌控的入问。
就好比我上面說的,你想讓第一個(gè)視頻和第二個(gè)視頻同時(shí)放稀颁,那么一個(gè)肯定會(huì)壓住另一個(gè)芬失,你合并之后看到的還是一個(gè)視頻,那么你其實(shí)可以改變一個(gè)視頻的LayerInstruction的opacity匾灶,讓她變成0.5棱烂,那么不就可以同時(shí)看見兩個(gè)了么,跟雙重曝光似得阶女。
貼段代碼颊糜。之前微博上有人問我怎么改透明度的問題,這里給出解答秃踩。
// 第二個(gè)視頻的架構(gòu)層AVMutableVideoCompositionLayerInstruction *secondlayerInstruction = [AVMutableVideoCompositionLayerInstructionvideoCompositionLayerInstructionWithAssetTrack:secondTrack];? ? [secondlayerInstructionsetOpacityRampFromStartOpacity:0.7toEndOpacity:0.2timeRange:CMTimeRangeMake(kCMTimeZero, firstAsset.duration)];? ? [secondlayerInstructionsetTransform:CGAffineTransformIdentityatTime:kCMTimeZero];
最后就是設(shè)置最終配置了衬鱼。貼代碼就好了,都是套路憔杨,看懂了鸟赫,記住了自然就會(huì)了。
// 這個(gè)地方你把數(shù)組順序倒一下消别,視頻上下位置也跟著變了抛蚤。mainInstruction.layerInstructions = [NSArrayarrayWithObjects:secondlayerInstruction,firstlayerInstruction,nil];? ? mainComposition = [AVMutableVideoCompositionvideoComposition];? ? mainComposition.instructions = [NSArrayarrayWithObjects:mainInstruction,nil];? ? mainComposition.frameDuration =CMTimeMake(1,30);? ? mainComposition.renderSize =CGSizeMake(320,240);
然后用AVAssetExportSession導(dǎo)出就行了。
最后附上我的DEMO地址妖啥。有興趣的可以學(xué)習(xí)。我的DEMO里付了一個(gè)mp4格式的視頻对碌,你們使用的時(shí)候只需要導(dǎo)入一個(gè)自己拍的視頻合并完之后會(huì)自動(dòng)導(dǎo)入系統(tǒng)相冊(cè)荆虱,你們可以比較兩個(gè)視頻然后看看導(dǎo)出的結(jié)果。
https://github.com/pingguo-zangqilong/VideoDemo
如果你認(rèn)為這篇文章不錯(cuò)朽们,也有閑錢怀读,那你可以用支付寶掃描下方二維碼隨便捐助一點(diǎn),以慰勞作者的辛苦