在 Swift 中的 WhatsApp 上共享合并的图像和视频时视频质量较差

问题描述 投票:0回答:1

我正在尝试在 Swift 中组合图像和视频,然后在 WhatsApp 上分享。但是,我遇到了一个问题,共享视频的质量似乎很低,并且模糊。

有趣的是,当其他具有类似功能的应用程序时,视频质量仍然很好。我的源代码是否存在可能导致此问题的潜在问题?

func mergeVideoWithFullSizeImage(videoURL: URL, image: UIImage, outputURL: URL, completion: @escaping (Bool, Error?) -> Void) {
   
    // Remove the existing output file if it exists
    removeFileIfExists(atURL: outputURL)
    
    let videoAsset = AVURLAsset(url: videoURL)
    let videoTrack = videoAsset.tracks(withMediaType: .video)[0]
    let imageLayer = CALayer()
    imageLayer.contents = image.cgImage
    let videoSize = videoAsset.tracks(withMediaType: .video)[0].naturalSize
    
    // Calculate the scale factor to fit the image to the video frame
    let scaleFactor = max(videoSize.width / image.size.width, videoSize.height / image.size.height)
    let scaledImageSize = CGSize(width: image.size.width * scaleFactor, height: image.size.height * scaleFactor)
    
    // Position the image at the center of the video frame
    let imagePosition = CGPoint(x: (videoSize.width - scaledImageSize.width) / 2, y: (videoSize.height - scaledImageSize.height) / 2)
    
    // Set the layer's frame and position
    imageLayer.frame = CGRect(origin: imagePosition, size: scaledImageSize)
    
    let videoComposition = AVMutableVideoComposition()
    videoComposition.renderSize = videoSize
    videoComposition.frameDuration = CMTime(value: 1, timescale: 30) // 30 fps
    
    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRange(start: .zero, duration: videoAsset.duration)
    
    let videoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
    instruction.layerInstructions = [videoLayerInstruction]
    videoComposition.instructions = [instruction]
    
    // Create a parent layer for both video and image layers
    let parentLayer = CALayer()
    let videoLayer = CALayer()
    
    // Set the video layer's frame to match the video composition size
    videoLayer.frame = CGRect(origin: .zero, size: videoSize)
    
    // Add the video and image layers to the parent layer
    parentLayer.addSublayer(videoLayer)
    parentLayer.addSublayer(imageLayer)
    
    // Set the parent layer as the composition's animation tool
    videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
    
    let mutableComposition = AVMutableComposition()
    let videoTrackComposition = mutableComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
    
    try? videoTrackComposition?.insertTimeRange(CMTimeRange(start: .zero, duration: videoAsset.duration), of: videoTrack, at: .zero)
    
    let mainInstruction = AVMutableVideoCompositionInstruction()
    mainInstruction.timeRange = CMTimeRange(start: .zero, duration: videoAsset.duration)
    mainInstruction.layerInstructions = [videoLayerInstruction]
    
    videoComposition.instructions = [mainInstruction]
    
    // Use a WhatsApp-compatible export preset
    let exportPreset = AVAssetExportPresetHighestQuality
    
    guard let exportSession = AVAssetExportSession(asset: mutableComposition, presetName: exportPreset) else {
        completion(false, nil)
        return
    }
    
    exportSession.outputURL = outputURL
    exportSession.outputFileType = .mp4
    exportSession.shouldOptimizeForNetworkUse = true
    exportSession.videoComposition = videoComposition
    
    exportSession.exportAsynchronously {
        DispatchQueue.main.async {
            switch exportSession.status {
            case .completed:
                completion(true, nil)
            case .failed:
                completion(false, exportSession.error)
            case .cancelled:
                completion(false, nil)
            default:
                break
            }
        }
    }
    
    
}
swift objective-c xcode swift3 xcode8
1个回答
0
投票

问题是你的图层,例如

parentLayer
,没有大小。您需要获取视频轨道的自然大小并将其用作图层的大小。

© www.soinside.com 2019 - 2024. All rights reserved.