思路
使用AVMutableComposition组合拼接出想要的分段组合方式,
反复播放通常要处理三个分段,1.重复之前的直接播放段 2.反复段 3.反复段之后的直接播放段.
逻辑比较简单 直接上代码
- (void)videoSectionReplay {
//测试数据
CMTimeRange replayTimeRange = CMTimeRangeMake(CMTimeMakeWithSeconds(3, 600), CMTimeMakeWithSeconds(3, 600));
NSUInteger replayCount = 3;
//测试资源
NSString *filePath4 = [[NSBundle mainBundle] pathForResource:@"timeMerge" ofType:@"MP4"];
AVAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:filePath4] options:@{}];
AVAssetTrack *videoTrack = asset.videoTrack;
AVAssetTrack *audioTrack = asset.audioTrack;
//要重复的时间段 在视频轨道中就没有 无法继续处理直接返回
if (!CMTimeRangeContainsTimeRange(videoTrack.timeRange, replayTimeRange)) {
return;
}
//组合对象
AVMutableComposition *mutableComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *videoCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *audioCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
CMTime videoInsertOffset = kCMTimeZero;
CMTime audioInsertOffset = kCMTimeZero;
//如果有正常播放的前段 插入正常播放的前段
if (CMTIME_COMPARE_INLINE(replayTimeRange.start, !=, kCMTimeZero)) {
CMTime duration = CMTimeSubtract(replayTimeRange.start, videoTrack.timeRange.start);
CMTimeRange prePassThroughTimeRange = CMTimeRangeMake(videoTrack.timeRange.start, duration);
[videoCompositionTrack insertTimeRange:prePassThroughTimeRange ofTrack:videoTrack atTime:videoInsertOffset error:nil];
[audioCompositionTrack insertTimeRange:prePassThroughTimeRange ofTrack:audioTrack atTime:audioInsertOffset error:nil];
videoInsertOffset = videoCompositionTrack.timeRange.duration;
audioInsertOffset = audioCompositionTrack.timeRange.duration;
}
//插入反复播放的片段
for (NSUInteger i=0; i<replayCount; i++) {
[videoCompositionTrack insertTimeRange:replayTimeRange ofTrack:videoTrack atTime:videoInsertOffset error:nil];
[audioCompositionTrack insertTimeRange:replayTimeRange ofTrack:audioTrack atTime:audioInsertOffset error:nil];
videoInsertOffset = videoCompositionTrack.timeRange.duration;
audioInsertOffset = audioCompositionTrack.timeRange.duration;
}
//如果后面还有需要直接播放的片段 插入后面的直接播放的段
CMTime replayEndTime = CMTimeAdd(replayTimeRange.start, replayTimeRange.duration);
if (CMTIME_COMPARE_INLINE(videoTrack.timeRange.duration, >, replayEndTime)) {
CMTime duration = CMTimeSubtract(videoTrack.timeRange.duration, replayEndTime);
CMTimeRange backTimeRange = CMTimeRangeMake(replayEndTime, duration);
[videoCompositionTrack insertTimeRange:backTimeRange ofTrack:videoTrack atTime:videoInsertOffset error:nil];
[audioCompositionTrack insertTimeRange:backTimeRange ofTrack:audioTrack atTime:audioInsertOffset error:nil];
videoInsertOffset = videoCompositionTrack.timeRange.duration;
audioInsertOffset = audioCompositionTrack.timeRange.duration;
}
combineResultTestViewController *vc = [[combineResultTestViewController alloc] initWithAsset:mutableComposition];
[self.navigationController pushViewController:vc animated:YES];
}
还用到了一个简单的扩展
@implementation AVAsset (AHSVAsset)
- (AVAssetTrack *)videoTrack {
AVAssetTrack *videoTrack = [self tracksWithMediaType:AVMediaTypeVideo].firstObject;
return videoTrack;
}
- (AVAssetTrack *)audioTrack {
AVAssetTrack *audioTrack = [self tracksWithMediaType:AVMediaTypeAudio].firstObject;
return audioTrack;
}
@end
网友评论