问题描述
我正在添加 CALayer 以在视频上添加贴纸图像。哪个工作得很好。我正在以纵向模式拍摄图像或录制视频,例如 snapchat 和 TikTok。
问题是当我从图库中选择视频并在附加的黄色区域添加贴纸时。合并视频顶部的图像。压缩失败。
我想在任何我想要的视频顶部添加图像。当我在合并后播放时,图像应该在所需位置可见。对于图像,我只是捕获拖动视图的屏幕截图并将其作为图像传递给我的方法。这适用于从应用捕获的图像或录制视频,但不适用于图库媒体。
let asset = AVURLAsset(url: inputURL)
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.")
handler(nil)
return
}
do {
// 1
let timeRange = CMTimeRange(start: .zero,duration: asset.duration)
// 2
try compositionTrack.insertTimeRange(timeRange,of: assetTrack,at: .zero)
// 3
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 {
// 4
print(error)
handler(nil)
return
}
compositionTrack.preferredTransform = assetTrack.preferredTransform
let videoInfo = orientation(from: assetTrack.preferredTransform)
var videoSize: CGSize
if videoInfo.isPortrait {
videoSize = CGSize(
width: assetTrack.naturalSize.height,height: assetTrack.naturalSize.width)
} else {
videoSize = assetTrack.naturalSize
}
let videoLayer = CALayer()
videoLayer.frame = CGRect(origin: .zero,size: videoSize)
let overlayLayer = CALayer()
overlayLayer.frame = CGRect(origin: .zero,size: videoSize)
guard let image = capturedimage else {
return
}
let imageLayer = CALayer()
imageLayer.frame = overlayLayer.frame
imageLayer.contents = image.cgImage
overlayLayer.addSublayer(imageLayer)
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]
let filename = NSUUID().uuidString + ".mp4"
_ = Utility.delete(fileName: filename)
let compressedURL = NSURL.fileURL(withPath: NstemporaryDirectory() + filename)
let urlAsset = AVURLAsset(url: inputURL,options: nil)
guard let exportSession = AVAssetExportSession(asset: urlAsset,presetName: AVAssetExportPreset640x480) else {
handler(nil)
return
}
exportSession.outputURL = compressedURL
exportSession.outputFileType = .mp4
exportSession.shouldOptimizeforNetworkUse = true
exportSession.videoComposition = videoComposition
exportSession.exportAsynchronously { () -> Void in
switch exportSession.status {
case .unkNown:
print("unkNown")
handler(nil)
break
case .waiting:
print("waiting")
handler(nil)
break
case .exporting:
print("exporting")
handler(nil)
break
case .completed:
print("File size before compression: \(inputURL.fileSizeString)")
print("File size after compression: \(compressedURL.fileSizeString)")
handler(compressedURL)
case .Failed:
print("Failed")
handler(nil)
break
case .cancelled:
print("cancelled")
handler(nil)
break
@unkNown default:
print("none")
handler(nil)
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)