我有多个AVAsset
视频,我使用 timeRanges 在AVComposition
. 每个视频都有一个关联AVVideoComposition
,它使用animationTool
向视频添加覆盖层。我希望能够以AVVideoCompositions
类似于的方式将它们串在一起,AVComposition
以便与每个 AVAsset 关联的层在指定的开始/结束时间显示/隐藏。我怎样才能做到这一点?
我目前使用此代码创建具有单个 AVAsset 的 for AVVideoComposition
:AVComposition
// 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
}