微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

第二次导出AVAsset使视频空白

如何解决第二次导出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 举报,一经查实,本站将立刻删除。