在Video Swift上添加UIView层-以编程方式

问题描述

我正在尝试通过视频添加UIView,我使用的是这段代码,该代码来自我在互联网上找到的教学语言(overlay video功能代码如下:

func addViewToVideo(fromVideoAt videoURL: URL,withView: UIView,onComplete: @escaping (URL?) -> Void) {

    let asset = AVURLAsset(url: videoURL)
    let composition = AVMutableComposition()

    guard
        let compositionTrack = composition.addMutableTrack(
            withMediaType: .video,preferredTrackID: kCMPersistentTrackID_Invalid),let assetTrack = asset.tracks(withMediaType: .video).first
    else {
        print("Something is wrong with the asset.")
        onComplete(nil)
        return
    }

    do {
        let timeRange = CMTimeRange(start: .zero,duration: asset.duration)
        try compositionTrack.insertTimeRange(timeRange,of: assetTrack,at: .zero)

        if let audioAssetTrack = asset.tracks(withMediaType: .audio).first,let compositionAudioTrack = composition.addMutableTrack(
            withMediaType: .audio,preferredTrackID: kCMPersistentTrackID_Invalid) {
            try compositionAudioTrack.insertTimeRange(
                timeRange,of: audioAssetTrack,at: .zero)
        }
    } catch {
        print(error)
        onComplete(nil)
        return
    }

    compositionTrack.preferredTransform = assetTrack.preferredTransform

    let videoSize: CGSize = CGSize(width: assetTrack.naturalSize.height,height: assetTrack.naturalSize.width)

    let videoLayer = CALayer()
    videoLayer.frame = CGRect(origin: .zero,size: videoSize)
    let overlayLayer = CALayer()
    overlayLayer.frame = CGRect(origin: .zero,size: videoSize)

    addImage(imagePassed: self.upperView.asImage(),to: overlayLayer,videoSize: videoSize)


    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: composition.duration)
    videoComposition.instructions = [instruction]
    let layerInstruction = compositionLayerInstruction(
        for: compositionTrack,assetTrack: assetTrack)
    instruction.layerInstructions = [layerInstruction]

    guard let export = AVAssetExportSession(
            asset: composition,presetName: AVAssetExportPresetHighestQuality)
    else {
        print("Cannot create export session.")
        onComplete(nil)
        return
    }

    let videoName = UUID().uuidString
    let exportURL = URL(fileURLWithPath: NstemporaryDirectory())
        .appendingPathComponent(videoName)
        .appendingPathExtension("mov")

    export.videoComposition = videoComposition
    export.outputFileType = .mov
    export.outputURL = exportURL

    export.exportAsynchronously {
        dispatchQueue.main.async {
            switch export.status {
            case .completed:
                onComplete(exportURL)
            default:
                print("Something went wrong during export.")
                print(export.error ?? "unkNown error")
                onComplete(nil)
                break
            }
        }
    }
}

private func addImage(imagePassed: UIImage,to layer: CALayer,videoSize: CGSize) {
    let image = imagePassed
    let imageLayer = CALayer()

    let aspect: CGFloat = image.size.width / image.size.height
    let width = videoSize.width
    let height = width / aspect
    imageLayer.frame = CGRect(
        x: 0,y: -height * 0.15,width: width,height: height)

    imageLayer.contents = image.cgImage
    layer.addSublayer(imageLayer)
}

private func compositionLayerInstruction(for track: AVCompositionTrack,assetTrack: AVAssetTrack) -> AVMutableVideoCompositionLayerInstruction {
    let instruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track)
    let transform = assetTrack.preferredTransform

    instruction.setTransform(transform,at: .zero)

    return instruction
}

它工作得很好,但是我不知道当URL来自front camera时是什么原因,所以视频仅显示在视图的上部。 就像一半的视频和一半的黑屏。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)