繁体   English   中英

如何使用avfoundation合并视频剪辑?

[英]how to merge video clips using avfoundation?

我已经成功地将视频片段合并到一个视频中,但是在最终的合并视频中却遇到了问题,每个视频片段结束后,最终的视频都会显示一个白框。 我已经尝试了很多以消除此问题,但找不到成功。 请在下面查看我的代码。

func merge(arrayVideos:[AVAsset], completion:@escaping (_ exporter: AVAssetExportSession) -> ()) -> Void {

    let mainComposition = AVMutableComposition()
    let compositionVideoTrack = mainComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
    compositionVideoTrack?.preferredTransform = CGAffineTransform(rotationAngle: .pi / 2)
    let soundtrackTrack = mainComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
    var time:Double = 0.0

    for (index, videoAsset) in arrayVideos.enumerated() {
        let atTime = CMTime(seconds: time, preferredTimescale: 1)
        try! compositionVideoTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: .video)[0], at: atTime)
        try! soundtrackTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: .audio)[0], at: atTime)
        time += videoAsset.duration.seconds
    }

    let outputFileURL = URL(fileURLWithPath: NSTemporaryDirectory() + "merge.mp4")
    print("final URL:\(outputFileURL)")
    let fileManager = FileManager()

    do {
        try fileManager.removeItem(at: outputFileURL)
    } catch let error as NSError {
        print("Error: \(error.domain)")
    }

    let exporter = AVAssetExportSession(asset: mainComposition, presetName: AVAssetExportPresetHighestQuality)
    exporter?.outputURL = outputFileURL
    exporter?.outputFileType = AVFileType.mp4
    exporter?.shouldOptimizeForNetworkUse = true
    exporter?.exportAsynchronously {
        DispatchQueue.main.async {
            completion(exporter!)
        }
    }
}

不要使用Double来跟踪插入时间,因为舍入误差会导致间隙。 并且在转换秒数时不要使用preferredTimescale ,而将秒数有效地四舍五入为整秒(1000是更常见的时标)。

而是使用初始化为kCMTimeZeroCMTime来跟踪插入时间,并使用CMTimeAdd来提前插入时间。

还有一件事:视频和音频轨道的持续时间可能不同,尤其是在录制时。 因此,为了使事情保持同步,您可能需要使用CMTimeRangeGetIntersection获取资产中音频和视频的通用时间范围,然后使用result插入合成中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM