我想将视频与图像合并,但合并后显示黑屏

I want to merge video with image but after merging it's showing black screen

我已经从后端拍摄了一个视频 URL,我想与图像结合。所以我在名为AnimationLayer的ParentLayer上添加了VideoLayer,ImageLayer。

Merge Video and images 后,似乎有 1 个黑屏。

我该如何解决这个错误?

 func MergeVideo1(_ vidioUrlString: String?, with img: UIImage?, With VideoName : String)
    {
        
        guard let videoUrl = URL(string: vidioUrlString ?? "") else { return  }
        
        let videoUrlAsset = AVURLAsset(url: videoUrl, options: nil)
        
        // Setup `mutableComposition` from the existing video
        let mutableComposition = AVMutableComposition()
        let videoAssetTrack = videoUrlAsset.tracks(withMediaType: AVMediaType.video).first!
        
        let videoCompositionTrack = mutableComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
        videoCompositionTrack!.preferredTransform = videoAssetTrack.preferredTransform
   
        try! videoCompositionTrack!.insertTimeRange(CMTimeRange(start:CMTime.zero, duration:videoAssetTrack.timeRange.duration), of: videoAssetTrack, at: CMTime.zero)
        let audioAssetTrack = videoUrlAsset.tracks(withMediaType: AVMediaType.audio).first!
        let audioCompositionTrack = mutableComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)
        try! audioCompositionTrack!.insertTimeRange(CMTimeRange(start: CMTime.zero, duration:audioAssetTrack.timeRange.duration), of: audioAssetTrack , at: CMTime.zero)
        
        // Create a `videoComposition` to represent the `foregroundImage`
        let videoSize: CGSize = videoCompositionTrack!.naturalSize
        let frame = CGRect(x: 0.0, y: 0.0, width: videoSize.width, height: videoSize.height)
        
        
           
         let imgLogoMix = UIImage(named: "icn_RandomDownload")
        //Logo
        let imageLayer_LOGO = CALayer()
        imageLayer_LOGO.contents = imgLogoMix.cgImage
        imageLayer_LOGO.frame = frame
        
        
        //Frame
        let imageLayer = CALayer()
        imageLayer.contents = img?.cgImage
        imageLayer.frame = frame
        
        let videoLayer = CALayer()
        videoLayer.frame = frame
        
        let animationLayer = CALayer()
        animationLayer.frame = frame
        
        animationLayer.addSublayer(videoLayer)
        animationLayer.addSublayer(imageLayer)
        animationLayer.addSublayer(imageLayer_LOGO)
        
        imageLayer.bringToFront()
        imageLayer_LOGO.bringToFront()

        
        
        let videoComposition = AVMutableVideoComposition(propertiesOf: (videoCompositionTrack?.asset!)!)
      
      
        videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: animationLayer)
        
        
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let DirPath = paths[0].appendingPathComponent("CREATE_IMAGE")
        //finalPath = DirPath.path +  "/myVideo.mp4"
        
        finalPath = DirPath.path +  "/\(VideoName).mp4"
        
        if FileManager.default.fileExists(atPath: finalPath) {
            do {
                try FileManager.default.removeItem(atPath: finalPath)
            } catch {
            }
        }
        
        let exportSession = AVAssetExportSession( asset: mutableComposition, presetName: AVAssetExportPresetHighestQuality)!
        exportSession.videoComposition = videoComposition
        //  exportSession.outputURL = destinationFilePath
        exportSession.outputURL = URL(fileURLWithPath: finalPath)
        exportSession.outputFileType = AVFileType.mp4
    
        
        
        exportSession.exportAsynchronously(completionHandler: {
            switch exportSession.status {
            case AVAssetExportSession.Status.failed:
                print("failed")
                SKActivityHUD.DismissHUD()
                print(exportSession.error ?? "unknown error")
            case AVAssetExportSession.Status.cancelled:
                print("cancelled")
                SKActivityHUD.DismissHUD()
                print(exportSession.error ?? "unknown error")
            default:
                print("Movie complete")
                // SKActivityHUD.DismissHUD()
              
            }
        })
    }

编辑了上面的代码
let videoComposition = AVMutableVideoComposition()
        videoComposition.frameDuration = CMTimeMake(value: 1, timescale: Int32(videoCompositionTrack?.nominalFrameRate ?? 300))
  videoComposition.renderSize = videoSize
 videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: animationLayer)
 let instruction = AVMutableVideoCompositionInstruction()
 instruction.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: mutableComposition.duration)
 let videotrack = mutableComposition.tracks(withMediaType: AVMediaType.video)[0] as AVAssetTrack
let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videotrack)
instruction.layerInstructions = NSArray(object: layerinstruction) as [AnyObject] as! [AVVideoCompositionLayerInstruction]
videoComposition.instructions = [instruction]

以上代码刚刚替换为

  let videoComposition = AVMutableVideoComposition()
    videoComposition.frameDuration = CMTimeMake(value: 1, timescale: Int32(videoCompositionTrack?.nominalFrameRate ?? 300))
    videoComposition.renderSize = videoSize
    videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: animationLayer)

  
    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: mutableComposition.duration)
    let videotrack = mutableComposition.tracks(withMediaType: AVMediaType.video)[0] as AVAssetTrack
    let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videotrack)
    let rgb = CGColorSpaceCreateDeviceRGB()
    let myColor : [CGFloat] = [1.0, 1.0, 1.0, 1.0] //white
    let ref = CGColor(colorSpace: rgb, components: myColor)
    instruction.backgroundColor = ref
    instruction.layerInstructions = NSArray(object: layerinstruction) as [AnyObject] as! [AVVideoCompositionLayerInstruction]
    videoComposition.instructions = [instruction]