我正在使用AVMutableComposition()
添加这样的轨道将多个视频文件拼接成一个:
let compositionVideoTrack = mainComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
let soundtrackTrack = mainComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
private var insertTime = CMTime.zero
for videoAsset in arrayVideos {
try! compositionVideoTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: .video)[0], at: insertTime)
try! soundtrackTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: .audio)[0], at: insertTime)
insertTime = CMTimeAdd(insertTime, videoAsset.duration)
}
然后将它们导出AVAssetExportSession(asset: mainComposition, presetName: AVAssetExportPresetMediumQuality)
到 .mov 文件中。
这会将拼接的视频保存到 url,我可以使用 AVAsset 访问并显示给用户。之后,我尝试将图像叠加层添加到视频中并再次导出。
在第二种方法中,我从 url 实例化 AVAsset AVAsset(url: fileUrl)
。并创造新的AVMutableComposition()
. 我将视频和音频轨道添加到资产的合成中:
compositionTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
compositionTrack.insertTimeRange(timeRange, of: asset.tracks(withMediaType: .video)[], at: .zero)
...
然后我使用图层将叠加层添加到视频中,AVVideoCompositionCoreAnimationTool()
如下所示:
let videoLayer = CALayer()
videoLayer.frame = CGRect(origin: .zero, size: videoSize)
let overlayLayer = CALayer()
overlayLayer.frame = CGRect(origin: .zero, size: videoSize)
overlayLayer.contents = watermark.cgImage
overlayLayer.contentsGravity = .resizeAspect
let outputLayer = CALayer()
outputLayer.frame = CGRect(origin: .zero, size: videoSize)
outputLayer.addSublayer(videoLayer)
outputLayer.addSublayer(overlayLayer)
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: asset.duration)
videoComposition.instructions = [instruction]
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: assetTrack)
layerInstruction.setTransform(assetTrack.preferredTransform, at: .zero)
instruction.layerInstructions = [layerInstruction]
然后我以与第一次导出相同的方式导出视频。
问题是当我结合它时。 如果我只使用第二种方法导出一些示例视频,则会添加到视频的叠加层,并且一切都符合预期。如果我使用第一种方法拼接视频,那么视频就会完美拼接。但是,当我结合这些方法时,生成的视频是黑色的空白屏幕(音频和叠加效果很好,生成的视频持续时间也很合适)。