代码之家  ›  专栏  ›  技术社区  ›  Ashley Mills

AVMutableComposition-连接的视频资产在第一个资产之后停止

  •  0
  • Ashley Mills  · 技术社区  · 9 年前

    我使用以下代码连接多个 AVURLAssets :

    AVMutableComposition * movie = [AVMutableComposition composition];
    
    CMTime offset = kCMTimeZero;
    
    for (AVURLAsset * asset in assets) {
        AVMutableCompositionTrack *compositionVideoTrack = [movie addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
        AVMutableCompositionTrack *compositionAudioTrack = [movie addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    
        AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
        AVAssetTrack *assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
    
        CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
        NSError * error = nil;
    
        if (![compositionVideoTrack insertTimeRange: timeRange ofTrack: assetVideoTrack atTime: offset error: &error]) {
            NSLog(@"Error adding video track - %@", error);
        }
        if (![compositionAudioTrack insertTimeRange: timeRange ofTrack: assetAudioTrack atTime: offset error: &error]) {
            NSLog(@"Error adding audio track - %@", error);
        }
    
        offset = CMTimeAdd(offset, asset.duration);
    }
    

    合成的合成播放到所有原始资源的组合持续时间,音频播放正确,但仅播放第一个资源的视频,然后暂停到最后一帧。

    有没有想过我做错了什么?

    原始资产的排序与第一个视频和所有音频播放无关。

    2 回复  |  直到 9 年前
        1
  •  1
  •   Jonathan    9 年前

    您需要使用AVVideoCompositionInstructions的实例创建AVVideoComposition。看看这个 sample code .

    您感兴趣的代码将具有以下性质:

    AVMutableVideoCompositionLayerInstruction *videoCompositionLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:mutableVideoTrack];
    [self.layerInstructions addObject:videoCompositionLayerInstruction];
            AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
            passThroughInstruction.timeRange = trackTimeRange;
            passThroughInstruction.layerInstructions = @[videoCompositionLayerInstruction];
    [self.compositionInstructions addObject:passThroughInstruction];
    
        2
  •  0
  •   Ashley Mills    9 年前

    好吧,这是我的错。我会把 addMutableTrackWithMediaType: 在…内 这个 for 环真傻。修复如下,效果就像一个符咒!

    我会把这个留在这里,以防其他人有同样的问题。

    AVMutableComposition * movie = [AVMutableComposition composition];
    AVMutableCompositionTrack *compositionVideoTrack = [movie addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *compositionAudioTrack = [movie addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    
    CMTime offset = kCMTimeZero;
    
    for (AVURLAsset * asset in assets) {
    
        AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
        AVAssetTrack *assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
    
        CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
        NSError * error = nil;
    
        if (![compositionVideoTrack insertTimeRange: timeRange ofTrack: assetVideoTrack atTime: offset error: &error]) {
            NSLog(@"Error adding video track - %@", error);
        }
        if (![compositionAudioTrack insertTimeRange: timeRange ofTrack: assetAudioTrack atTime: offset error: &error]) {
            NSLog(@"Error adding audio track - %@", error);
        }
    
        offset = CMTimeAdd(offset, asset.duration);
    }