使用AVFoundation對(duì)視頻進(jìn)行處理

關(guān)鍵字:AVFoundation,AVAsset,AVComposition,AVVideoComposition,AVVideoCompositionInstruction,AVVideoCompositionLayerInstruction

最近做了一個(gè)關(guān)于視頻處理的項(xiàng)目释牺,剛開始的需求大概只有:

  • 對(duì)視頻制定區(qū)域進(jìn)行裁剪
  • 對(duì)幾段視頻進(jìn)行裁剪拼接
  • 對(duì)視頻及音頻進(jìn)行拼接

遇到不會(huì)做的需求陵叽,很習(xí)慣就是Google一下別人的Demo是怎么做的要尔,然后大概看一下是如何實(shí)現(xiàn)的晌畅,然后拿過(guò)來(lái)修改一下挂据。嗯踢故,按照我后來(lái)學(xué)習(xí)了一下AVFoundation這個(gè)庫(kù)之后孝常,感覺(jué)我第一階段的工作自己應(yīng)該是幾乎沒(méi)弄懂什么状共。好了,工作又有進(jìn)一步的需求了:

  • 實(shí)現(xiàn)視頻間的過(guò)渡效果
  • 實(shí)現(xiàn)多段視頻分屏顯示的效果
  • 實(shí)現(xiàn)視頻添加字幕尘应,以及字幕動(dòng)畫效果

這些內(nèi)容Google出來(lái)的內(nèi)容惶凝,很難明白到底是怎么實(shí)現(xiàn)的,已經(jīng)其實(shí)什么都沒(méi)說(shuō)出來(lái)犬钢,很多的都是這個(gè)復(fù)制另一個(gè)的代碼苍鲜,修改一下,這完全不能做到讓你學(xué)會(huì)使用玷犹,大多都是讓你學(xué)會(huì)搬磚混滔。

還好我找到一本書AVFoundation秘籍

對(duì)于媒體的編輯,主要看熟里面的第九章以及第十一章,進(jìn)階的是在第十二章坯屿。

媒體的組合和編輯

在iOS中油湖,所有的音視頻都被抽象成AVAsset對(duì)象,這樣一來(lái)就可以簡(jiǎn)化了不同格式的媒體领跛,并且可以將所有的音視頻都是用統(tǒng)一的接口進(jìn)行處理肺魁,這很符合面向?qū)ο蟮牧?xí)慣。
如果我們有使用過(guò)一些音視頻剪切的工具隔节,其實(shí)可以看到在處理剪切合成的時(shí)候鹅经,你的每一段素材,在進(jìn)行剪切以及合并之后怎诫,其實(shí)仍然是可以進(jìn)行單獨(dú)播放已經(jīng)繼續(xù)編輯的一個(gè)實(shí)體瘾晃,這個(gè)原理跟iOS的媒體組合和編輯是差不多的。

組合類.png

其實(shí)可以簡(jiǎn)單的理解成:

  • 我們平時(shí)播放的AVAsset幻妓,是由多段完整的AVAssetTrack蹦误,其中最簡(jiǎn)單的就是包含一段完整AVMediaTypeVideo類型的AVAssetTrack,以及一段完整AVMediaTypeAudio類型的AVAssetTrack肉津。
  • AVAssetTrack用于提供接口對(duì)媒體的軌道進(jìn)行操作强胰。
  • AVComposition這個(gè)組合的類,顧名思義是用于負(fù)責(zé)描述多個(gè)AVAssetTrack組合的關(guān)系妹沙,由于他是繼承于AVAsset的偶洋,因此他也是可以單獨(dú)作為AVAsset來(lái)使用,這里非常重要距糖。
  • AVCompositionTrackSegment玄窝,軌道的片段,不過(guò)目前我還沒(méi)有需要使用悍引。

于是使用上面類圖恩脂,我們能做什么呢?我們能簡(jiǎn)單的將幾個(gè)視頻首尾拼接成一個(gè)視頻進(jìn)行播放導(dǎo)出趣斤,以及將音頻視頻進(jìn)行簡(jiǎn)單的拼接處理(ps:這里的視頻拼接不能在同一時(shí)刻有另外的視頻在播放俩块,不然會(huì)出現(xiàn)黑屏的現(xiàn)象,解決方法會(huì)在后面出現(xiàn))浓领。

    //首先定義兩個(gè)需要操作的資源
    AVAsset *assetA = [AVAsset assetWithURL:[NSURL URLWithString:@"A"]];
    AVAsset *assetB = [AVAsset assetWithURL:[NSURL URLWithString:@"B"]];
    
    //定義兩個(gè)資源的軌道
    AVAssetTrack *trackA = [assetA tracksWithMediaType:AVMediaTypeVideo].firstObject;
    AVAssetTrack *trackB = [assetB tracksWithMediaType:AVMediaTypeVideo].firstObject;
    
    //定義一個(gè)用于操作資源組合的可變資源
    AVMutableComposition *composition = [AVMutableComposition composition];
    
    //定義兩個(gè)資源的組合軌道
    AVMutableCompositionTrack *compositionTrackA = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *compositionTrackB = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    
    //為兩個(gè)組合軌道分別插入0s-3s段的資源玉凯,a在0-3s播放,b在3-6s播放
    [compositionTrackA insertTimeRange:CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(3, NSEC_PER_SEC)) ofTrack:trackA atTime:kCMTimeZero error:nil];
    [compositionTrackB insertTimeRange:CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(3, NSEC_PER_SEC)) ofTrack:trackB atTime:CMTimeMakeWithSeconds(3, NSEC_PER_SEC) error:nil];
    
    //到這里就可以直接使用composition進(jìn)行播放

    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:composition];
    AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];

創(chuàng)建視頻的過(guò)渡效果

上面的AVComposition是以資源軌道為單位的對(duì)不同媒體資源進(jìn)行組合镊逝,然后對(duì)于音頻視頻還有更進(jìn)一步的細(xì)分壮啊,這也為創(chuàng)建更多視頻效果提供了方便嫉鲸。下面先說(shuō)對(duì)于視頻的組合撑蒜。
以視頻添加過(guò)渡效果為例,還記得上面說(shuō)的兩個(gè)視頻,不能重疊在一起播放的問(wèn)題嗎座菠?這里就以這個(gè)為例狸眼。不過(guò)需要先引入一些概念。

視頻組合類.png

  • AVVideoComposition浴滴,視頻組合類拓萌,類似上面的AVComposition概念,不過(guò)這里是對(duì)一個(gè)媒體資源中升略,負(fù)責(zé)所有視頻資源組合關(guān)系的一個(gè)類微王,跟AVComposition一點(diǎn)關(guān)系都沒(méi)有。這個(gè)類除了可以包含視頻組合信息之外品嚣,還能配置視頻的渲染尺寸炕倘,縮放,和幀時(shí)長(zhǎng)等屬性翰撑。
  • AVVideoCompositionInstruction,AVVideoCompostion是由一組AVVideoCompositionInstruction對(duì)象格式定義的指令組成的罩旋。這個(gè)對(duì)象提供的最關(guān)鍵的信息是組合對(duì)象時(shí)間軸內(nèi)的時(shí)間范圍信息,其實(shí)就是表明這個(gè)視頻組合的開始時(shí)間和持續(xù)時(shí)間眶诈。要執(zhí)行的組合特質(zhì)是通過(guò)AVVideoCompositionLayerInstruction
  • AVVideoCompositionLayerInstruction涨醋,用于定義給定視頻軌道應(yīng)用的模糊,變形和裁剪效果逝撬。
    PS:AVVideoComposition并不直接與AVCompostion相關(guān)浴骂,相反看上面視頻組合類.png,這些對(duì)象是和類似AVPlayItem等客戶端相關(guān)聯(lián)宪潮,在播放組合或進(jìn)行其他處理時(shí)使用這些對(duì)象靠闭。

下面的例子,其實(shí)我們可以對(duì)于每一段AVVideoCompositionInstrction都自行定義坎炼,但是有更簡(jiǎn)便的方法愧膀,為何不用呢?

    AVMutableVideoComposition *videoCompostion = [AVMutableVideoComposition videoCompositionWithPropertiesOfAsset:composition];

當(dāng)你使用這段代碼的時(shí)候谣光,會(huì)自動(dòng)生成一個(gè)默認(rèn)的AVVideoComposition檩淋,并且會(huì)自動(dòng)生成默認(rèn)的AVVideoCompositionInstructionAVVideoCompostionLayerInstruction萄金。那么它這個(gè)自動(dòng)生成的規(guī)則是怎么樣的呢蟀悦?多嘗試幾次不一樣的視頻組合,不難發(fā)現(xiàn):

  • 在時(shí)間軸延伸的方向氧敢,只要某一時(shí)刻的視頻組合數(shù)量發(fā)生變化日戈,那么就會(huì)產(chǎn)生一個(gè)新的AVVideoCompositionInstruction對(duì)象

例如:現(xiàn)在有三個(gè)視頻軌道,A孙乖,B浙炼,C(有數(shù)字的時(shí)刻代表視頻在該時(shí)間段有內(nèi)容份氧,#代表空)
軌道A:1 2 3 4 5 6 7 8 9
軌道B:1 2 3 # # # # # #
軌道C:1 2 3 4 5 6 # # #

  • 軌道A,B弯屈,C在1~3s內(nèi)都是有內(nèi)容的蜗帜,因此這會(huì)生成第一個(gè)AVVideoCompositionInstruction
  • 軌道A,C在3~6s內(nèi)有內(nèi)容资厉,由于這個(gè)時(shí)間段內(nèi)厅缺,視頻組合數(shù)量發(fā)生了改變,因此這里是第二個(gè)AVVideoCompositionInstruction
  • 最后在6-9s宴偿,只有軌道A有視頻湘捎,因此這里是第三個(gè)AVVideoCompositionInstruction

在我們生成了AVVideoCompositionInstruction之后,我們需要對(duì)里面的AVVideoCompositionLayerInstruction進(jìn)行自定義窄刘,具體這個(gè)過(guò)渡效果要什么樣子消痛,靠你自己組合視頻的數(shù)量,以及改變視頻的模糊都哭,變形和裁剪效果秩伞,這里就不一一實(shí)現(xiàn)了。

以上面3個(gè)軌道例子中的第3-6s作為演示
最終的效果是軌道A在3-6s播放的時(shí)候會(huì)漸漸模糊
    AVMutableVideoComposition *videoCompostion = [AVMutableVideoComposition videoCompositionWithPropertiesOfAsset:composition];
    
    for (AVMutableVideoCompositionInstruction *vci in videoCompostion.instructions) {
        if (vci.layerInstructions.count == 2) {
            AVMutableVideoCompositionLayerInstruction *fromLayerInstruction = (AVMutableVideoCompositionLayerInstruction *)vci.layerInstructions.firstObject;
//            AVVideoCompositionLayerInstruction *toLayerInstruction = vci.layerInstructions.firstObject;
            
            CMTimeRange timeRange = vci.timeRange;
            
            //漸變效果
            [fromLayerInstruction setOpacityRampFromStartOpacity:1.0 toEndOpacity:0 timeRange:timeRange];
            
        }
    }

動(dòng)畫圖層內(nèi)容

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末欺矫,一起剝皮案震驚了整個(gè)濱河市纱新,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌穆趴,老刑警劉巖脸爱,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異未妹,居然都是意外死亡簿废,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門络它,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)族檬,“玉大人,你說(shuō)我怎么就攤上這事化戳〉チ希” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵点楼,是天一觀的道長(zhǎng)扫尖。 經(jīng)常有香客問(wèn)我,道長(zhǎng)掠廓,這世上最難降的妖魔是什么换怖? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮蟀瞧,結(jié)果婚禮上沉颂,老公的妹妹穿的比我還像新娘条摸。我一直安慰自己,他們只是感情好兆览,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布屈溉。 她就那樣靜靜地躺著塞关,像睡著了一般抬探。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上帆赢,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天小压,我揣著相機(jī)與錄音,去河邊找鬼椰于。 笑死怠益,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瘾婿。 我是一名探鬼主播蜻牢,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼偏陪!你這毒婦竟也來(lái)了抢呆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤笛谦,失蹤者是張志新(化名)和其女友劉穎抱虐,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饥脑,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恳邀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了灶轰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谣沸。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖笋颤,靈堂內(nèi)的尸體忽然破棺而出鳄抒,到底是詐尸還是另有隱情,我是刑警寧澤椰弊,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布许溅,位于F島的核電站,受9級(jí)特大地震影響秉版,放射性物質(zhì)發(fā)生泄漏贤重。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一清焕、第九天 我趴在偏房一處隱蔽的房頂上張望并蝗。 院中可真熱鬧祭犯,春花似錦、人聲如沸滚停。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)键畴。三九已至最盅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間起惕,已是汗流浹背涡贱。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惹想,地道東北人问词。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像嘀粱,于是被迫代替她去往敵國(guó)和親激挪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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