iOS视频剪辑学习条记(AVAsset,AVMutableComposition)

源代码 2024-10-4 04:41:35 20 0 来自 中国
一个视频文件中包含了许多轨道(Track),比如一个或多个音频轨道,一个或多个视频轨道。我们可以对这些轨道中的数据举行各种利用(裁剪、拼接、旋转等)。
本次我用到的视频办理裁剪相关功能用到的类如下:
AVAsset:素材,比如出相册中取出的数据AVAssetTrack:素材的轨道AVMutableComposition:视频的工程文件(是AVAsset的子类,可以用来直接播放)AVMutableCompositionTrack:工程文件对应的轨道这里我的需求是要裁剪调一个视频素材的头尾,第一步须要获取到素材的视频轨道和音频轨道
AVAssetTrack *videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; AVAssetTrack *audioAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];第二步,创建工程文件,将素材的轨道数据导入到工程文件的轨道中
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];第三步,盘算须要裁剪的头和尾的range,然后将音频轨道和视频轨道都举行裁剪
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];到这里,我们已经将工程文件中的视频举行了裁剪,我们可以直接利用AVPlayer举行播放看裁剪乐成没有
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];固然,更多的是须要利用AVAssetExportSession将工程文件转码导出,代码如下:
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;    }}];至此,整个裁剪功能的重要代码已经完成。
遇到的坑

最初我参考别人的demo发现可以利用AVAssetExportSession的timeRange来实现裁剪。
CMTimeRange range = CMTimeRangeMake(start, duration); self.exportSession.timeRange = range;但是当裁剪的视频时长比较长时,这种方法在重新开始裁剪和裁剪视频后半部门在耗时上差别巨大。
比如我测试了30分钟的视频,我裁剪0-10分钟大概耗时8秒,但是裁剪20-30分钟耗时到达了惊人的60秒。我不清晰这个是由于底层来转码时选择转码范围的算法导致了这一征象照旧其他什么缘故起因。
终极我选择了利用上文中提到的切割轨道数据的方式根本做到了在30分钟的视频中切割10分钟,无论切割哪一段视频,都可以保持8秒完成切割和转码导出。
如有题目,请指正。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 16:47, Processed in 0.155705 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表