美文网首页
iOS 视频中片段反复播放特效实现

iOS 视频中片段反复播放特效实现

作者: 李田迎 | 来源:发表于2019-08-16 10:28 被阅读0次

    思路

    使用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
    

    相关文章

      网友评论

          本文标题:iOS 视频中片段反复播放特效实现

          本文链接:https://www.haomeiwen.com/subject/ulcfsctx.html