iOS視頻剪輯學(xué)習(xí)筆記(AVAsset,AVMutableComposition)

一個視頻文件中包含了很多軌道(Track)霸奕,比如一個或多個音頻軌道溜宽,一個或多個視頻軌道。我們可以對這些軌道中的數(shù)據(jù)進(jìn)行各種操作(裁剪质帅、拼接坑质、旋轉(zhuǎn)等)。

本次我用到的視頻打點(diǎn)裁剪相關(guān)功能用到的類如下:

AVAsset:素材临梗,比如出相冊中取出的數(shù)據(jù)
AVAssetTrack:素材的軌道
AVMutableComposition:視頻的工程文件(是AVAsset的子類涡扼,可以用來直接播放)
AVMutableCompositionTrack:工程文件對應(yīng)的軌道

這里我的需求是要裁剪調(diào)一個視頻素材的頭尾,第一步需要獲取到素材的視頻軌道和音頻軌道

 AVAssetTrack *videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
 AVAssetTrack *audioAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

第二步盟庞,創(chuàng)建工程文件吃沪,將素材的軌道數(shù)據(jù)導(dǎo)入到工程文件的軌道中

AVMutableComposition *mutableComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *audioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *videoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];

NSError *errorAudio;
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:audioAssetTrack atTime:kCMTimeZero error:&errorAudio];
NSError *errorVideo;
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:videoAssetTrack atTime:kCMTimeZero error:&errorVideo];

第三步,計(jì)算需要裁剪的頭和尾的range什猖,然后將音頻軌道和視頻軌道都進(jìn)行裁剪

CMTime start = CMTimeMakeWithSeconds(self.startTime, videoAsset.duration.timescale);
CMTime end = CMTimeMakeWithSeconds(self.stopTime - self.startTime, videoAsset.duration.timescale);
CMTime duration = CMTimeMakeWithSeconds(videoAsset.duration.value - self.stopTime, videoAsset.duration.timescale);
CMTimeRange range = CMTimeRangeMake(kCMTimeZero, start);
CMTimeRange range2 = CMTimeRangeMake(end, duration);
[videoTrack removeTimeRange: range];
[audioTrack removeTimeRange: range];
[videoTrack removeTimeRange: range2];
[audioTrack removeTimeRange: range2];

到這里票彪,我們已經(jīng)將工程文件中的視頻進(jìn)行了裁剪,我們可以直接使用AVPlayer進(jìn)行播放看裁剪成功沒有

AVPlayerViewController *playerController = [[AVPlayerViewController alloc] init];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:mutableComposition];
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
playerController.player = player;
[self presentViewController:playerController animated:true completion:nil];

當(dāng)然不狮,更多的是需要使用AVAssetExportSession將工程文件轉(zhuǎn)碼導(dǎo)出降铸,代碼如下:

AVAssetExportSession* exportSession = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetPassthrough];
NSURL *fileUrl = [NSURL fileURLWithPath:self.tempPath];
exportSession.outputURL = fileUrl;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:
     ^(void ) {
    switch ([exportSession status]) {
        case AVAssetExportSessionStatusFailed:
            NSLog(@"failed: %@", [[exportSession error] localizedDescription]);
            break;
        case AVAssetExportSessionStatusCancelled:
            NSLog(@"canceled");
            break;
        default:
            NSLog(@"success");
            break;
    }
}
];

至此,整個裁剪功能的主要代碼已經(jīng)完成摇零。

遇到的坑

最初我參考別人的demo發(fā)現(xiàn)可以使用AVAssetExportSession的timeRange來實(shí)現(xiàn)裁剪推掸。

 CMTimeRange range = CMTimeRangeMake(start, duration);
 self.exportSession.timeRange = range;

但是當(dāng)裁剪的視頻時長比較長時,這種方法在從頭開始裁剪和裁剪視頻后半部分在耗時上差別巨大。
比如我測試了30分鐘的視頻谅畅,我裁剪0-10分鐘大概耗時8秒登渣,但是裁剪20-30分鐘耗時達(dá)到了驚人的60秒。我不清楚這個是因?yàn)榈讓觼磙D(zhuǎn)碼時選擇轉(zhuǎn)碼范圍的算法導(dǎo)致了這一現(xiàn)象還是其他什么原因毡泻。
最終我選擇了使用上文中提到的切割軌道數(shù)據(jù)的方式基本做到了在30分鐘的視頻中切割10分鐘胜茧,無論切割哪一段視頻,都可以保持8秒完成切割和轉(zhuǎn)碼導(dǎo)出仇味。
如有問題呻顽,請指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丹墨,一起剝皮案震驚了整個濱河市芬位,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌带到,老刑警劉巖昧碉,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異揽惹,居然都是意外死亡被饿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門搪搏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狭握,“玉大人,你說我怎么就攤上這事疯溺÷勐” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵囱嫩,是天一觀的道長恃疯。 經(jīng)常有香客問我,道長墨闲,這世上最難降的妖魔是什么今妄? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮鸳碧,結(jié)果婚禮上盾鳞,老公的妹妹穿的比我還像新娘。我一直安慰自己瞻离,他們只是感情好腾仅,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著套利,像睡著了一般推励。 火紅的嫁衣襯著肌膚如雪鹤耍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天吹艇,我揣著相機(jī)與錄音,去河邊找鬼昂拂。 笑死受神,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的格侯。 我是一名探鬼主播鼻听,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼联四!你這毒婦竟也來了撑碴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朝墩,失蹤者是張志新(化名)和其女友劉穎醉拓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體收苏,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亿卤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鹿霸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片排吴。...
    茶點(diǎn)故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖懦鼠,靈堂內(nèi)的尸體忽然破棺而出钻哩,到底是詐尸還是另有隱情,我是刑警寧澤肛冶,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布街氢,位于F島的核電站,受9級特大地震影響睦袖,放射性物質(zhì)發(fā)生泄漏阳仔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一扣泊、第九天 我趴在偏房一處隱蔽的房頂上張望近范。 院中可真熱鬧,春花似錦延蟹、人聲如沸评矩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斥杜。三九已至虱颗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蔗喂,已是汗流浹背忘渔。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缰儿,地道東北人畦粮。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像乖阵,于是被迫代替她去往敵國和親宣赔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評論 2 359

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