1

我有多个AVAsset视频,我使用 timeRanges 在AVComposition. 每个视频都有一个关联AVVideoComposition,它使用animationTool向视频添加覆盖层。我希望能够以AVVideoCompositions类似于的方式将它们串在一起,AVComposition以便与每个 AVAsset 关联的层在指定的开始/结束时间显示/隐藏。我怎样才能做到这一点?

我目前使用此代码创建具有单个 AVAsset 的 for AVVideoCompositionAVComposition

// Create video composition
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = videoSize
videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(
  postProcessingAsVideoLayer: videoLayer,
  in: outputLayer
)

let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(
  start: .zero,
  duration: composition.duration
)
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionTrack)
layerInstruction.setTransform(assetTrack.preferredTransform, at: .zero)
instruction.layerInstructions = [layerInstruction]
videoComposition.instructions = [instruction]

这是我用于创建AVComposition具有多个资产的代码:

static func createFullVideo(from videos: [VideoItem]) -> AVComposition? {
    let newComposition = AVMutableComposition()
    
    guard let compositionTrack = newComposition.addMutableTrack(
        withMediaType: .video,
        preferredTrackID: kCMPersistentTrackID_Invalid) else {
        return nil
    }
    guard let compositionAudioTrack = newComposition.addMutableTrack(
            withMediaType: .audio,
            preferredTrackID: kCMPersistentTrackID_Invalid) else {
        return nil
    }

    var endTimeOfPreviousTrack: CMTime = .zero

    for video in videos {
        let composition = video.composition

        guard let assetTrack = composition.tracks(withMediaType: .video).first else {
            return nil
        }
        compositionTrack.preferredTransform = assetTrack.preferredTransform
        do {
            // Insert time range for video track in composition
            let timeRange = assetTrack.timeRange
            try compositionTrack.insertTimeRange(timeRange, of: assetTrack, at: endTimeOfPreviousTrack)

            // Get the audio track from the asset
            guard let audioAssetTrack = composition.tracks(withMediaType: .audio).first else {
                return nil
            }

            // Insert time range for audio track in composition
            try compositionAudioTrack.insertTimeRange(
              timeRange,
              of: audioAssetTrack,
              at: endTimeOfPreviousTrack
            )

            // Store end time of track
            endTimeOfPreviousTrack = CMTimeAdd(endTimeOfPreviousTrack,  assetTrack.timeRange.duration)
        } catch {
            return nil
        }
    return newComposition
}
4

0 回答 0