如何解决第二次导出AVAsset使视频空白
我正在使用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,of: videoAsset.tracks(withMediaType: .audio)[0],at: insertTime)
insertTime = CMTimeAdd(insertTime,videoAsset.duration)
}
然后使用AVAssetExportSession(asset: mainComposition,presetName: AVAssetExportPresetMediumQuality)
将它们导出到.mov文件。
这会将缝合的视频保存到url,我可以使用AVAsset访问该视频并将其显示给用户。之后,我尝试将图像叠加层添加到视频中并再次将其导出。
在第二种方法中,我从URL AVAsset(url: fileUrl)
实例化AVAsset。并创建新的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]
然后我以与第一次导出相同的方式导出视频。
问题是当我将其合并时。 如果仅使用第二种方法导出一些示例视频,则会在视频上添加叠加层,并且一切都按预期进行。 如果我使用第一种方法缝合视频,则视频将被完美缝合。但是,当我结合使用这些方法时,产生的视频是黑屏(音频和覆盖效果很好,产生的视频持续时间也合适)。
解决方法
该问题可能与AVVideoCompositionCoreAnimationTool()
有关。
通过使用另一种在第二个功能中向视频添加覆盖的技术,我能够解决此问题。我没有像这样使用AVVideoCompositionCoreAnimationTool()
来堆叠图层,而是使用了CIFilter
:
let watermarkFilter = CIFilter(name: "CISourceOverCompositing")!
let watermarkImage = CIImage(image: watermark)!
let videoComposition = AVVideoComposition(asset: asset) { (filteringRequest) in
let source = filteringRequest.sourceImage
watermarkFilter.setValue(source,forKey: kCIInputBackgroundImageKey)
let widthScale = source.extent.width/watermarkImage.extent.width
let heightScale = source.extent.height/watermarkImage.extent.height
watermarkFilter.setValue(watermarkImage.transformed(by: .init(scaleX: widthScale,y: heightScale)),forKey: kCIInputImageKey)
filteringRequest.finish(with: watermarkFilter.outputImage!,context: nil)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。