gpt4 book ai didi

ios - Swift 3 : How to add watermark on video ? AVVideoCompositionCoreAnimationTool iOS 10 问题

转载 作者:IT王子 更新时间:2023-10-29 05:36:21 28 4
gpt4 key购买 nike

此代码用于在 iOS9 上为视频添加水印和文本,但自 iOS10 以来它不再起作用。有一个 iOS 10 bug已提交,但 Apple 没有答复。我无法实现任何解决方法来在视频上添加水印和文本。使用此代码有时视频会成功导出,但大多数时候不会导出。

我应该如何使用 AVVideoCompositionCoreAnimationTool 才能像在 iOS9 上那样工作。

let videoComposition: AVMutableVideoComposition = AVMutableVideoComposition()

videoComposition.frameDuration = CMTimeMake(1, 60)
videoComposition.renderSize = CGSize(width: clipVideoTrack.naturalSize.height, height: clipVideoTrack.naturalSize.height)


let instruction: AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()

instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30))

// transformer is applied to set the video in portrait otherwise it is rotated by 90 degrees
let transformer: AVMutableVideoCompositionLayerInstruction =
AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)

let t1: CGAffineTransform = CGAffineTransform(translationX: clipVideoTrack.naturalSize.height, y: -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height)/2)

let t2: CGAffineTransform = t1.rotated(by: CGFloat(M_PI_2))

var finalTransform: CGAffineTransform = t2

transformer.setTransform(finalTransform, at: kCMTimeZero)

instruction.layerInstructions = NSArray(object: transformer) as! [AVVideoCompositionLayerInstruction]

videoComposition.instructions = NSArray(object: instruction) as! [AVVideoCompositionInstructionProtocol]



let mixComposition = AVMutableComposition()
let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)


do {
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, asset.duration), of: clipVideoTrack, at: kCMTimeZero)
} catch {
print(error)
}


//Add watermark


let myImage = UIImage(named: "logo")

let aLayer = CALayer()
aLayer.contents = myImage!.cgImage
aLayer.frame = CGRect(x: (clipVideoTrack.naturalSize.height*(self.view.bounds.width-45))/self.view.bounds.width, y: (clipVideoTrack.naturalSize.height*(self.view.bounds.width-40))/self.view.bounds.width, width: (clipVideoTrack.naturalSize.height*40)/self.view.bounds.width, height: (clipVideoTrack.naturalSize.height*40)/self.view.bounds.width)

let titleLayer = CATextLayer()
titleLayer.string = "text"
titleLayer.font = UIFont(name: "helvetica", size: 0)
titleLayer.fontSize = clipVideoTrack.naturalSize.height/16
titleLayer.shadowOpacity = 0.5
titleLayer.alignmentMode = kCAAlignmentCenter
titleLayer.frame = CGRect(x: 0, y: 0, width: clipVideoTrack.naturalSize.height, height: clipVideoTrack.naturalSize.height/6)
titleLayer.display()


let videoSize = asset.tracks(withMediaType: AVMediaTypeVideo)[0].naturalSize
let parentLayer = CALayer()
let videoLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: videoSize.height, height: videoSize.height)
videoLayer.frame = CGRect(x: 0, y: 0, width: videoSize.height, height: videoSize.height)

parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(aLayer)
parentLayer.addSublayer(titleLayer)


videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)



do { try FileManager.default.removeItem(at: filePath) }
catch let error as NSError {
NSLog("\(error), \(error.localizedDescription)")
}



var exportUrl: URL = filePath
self.videoUrl = filePath as NSURL


var exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetMediumQuality)

exporter!.videoComposition = videoComposition
exporter!.outputFileType = AVFileTypeQuickTimeMovie
exporter!.outputURL = URL(fileURLWithPath: exportUrl.path)


exporter!.exportAsynchronously(completionHandler: {

DispatchQueue.main.async {


self.view.layer.addSublayer(self.avPlayerLayer)

let item = AVPlayerItem(url: exportUrl)
self.player.replaceCurrentItem(with: item)

if (self.player.currentItem != nil) {
print("Starting playback!")
self.player.play()
}

}

})

请注意:如果我删除 AVVideoCompositionCoreAnimationTool,则视频始终会导出,但是视频上没有水印和文本。如何让它工作,以便 AVVideoCompositionCoreAnimationTool 不与 AVAssetExportSession 冲突?

有些人已经实现了 workaround使用 customVideoCompositorClassAVVideoCompositing 协议(protocol),但与过去的工作方式相比,这似乎是一个繁重的解决方法。

最佳答案

这个解决方案对我有用, super 简单, super 快速

func addWatermark(inputURL: URL, outputURL: URL, handler:@escaping (_ exportSession: AVAssetExportSession?)-> Void) {
let mixComposition = AVMutableComposition()
let asset = AVAsset(url: inputURL)
let videoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]
let timerange = CMTimeRangeMake(kCMTimeZero, asset.duration)

let compositionVideoTrack:AVMutableCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))!

do {
try compositionVideoTrack.insertTimeRange(timerange, of: videoTrack, at: kCMTimeZero)
compositionVideoTrack.preferredTransform = videoTrack.preferredTransform
} catch {
print(error)
}

let watermarkFilter = CIFilter(name: "CISourceOverCompositing")!
let watermarkImage = CIImage(image: UIImage(named: "waterMark")!)
let videoComposition = AVVideoComposition(asset: asset) { (filteringRequest) in
let source = filteringRequest.sourceImage.clampedToExtent()
watermarkFilter.setValue(source, forKey: "inputBackgroundImage")
let transform = CGAffineTransform(translationX: filteringRequest.sourceImage.extent.width - (watermarkImage?.extent.width)! - 2, y: 0)
watermarkFilter.setValue(watermarkImage?.transformed(by: transform), forKey: "inputImage")
filteringRequest.finish(with: watermarkFilter.outputImage!, context: nil)
}

guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset640x480) else {
handler(nil)

return
}

exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileType.mp4
exportSession.shouldOptimizeForNetworkUse = true
exportSession.videoComposition = videoComposition
exportSession.exportAsynchronously { () -> Void in
handler(exportSession)
}
}

抱歉,如果我没有发布如何调用此函数。我已经有一段时间没有触及该代码了,所以我希望这就足够了:

let outputURL = NSURL.fileURL(withPath: "TempPath")
let inputURL = NSURL.fileURL(withPath: "VideoWithWatermarkPath")
addWatermark(inputURL: inputURL, outputURL: outputURL, handler: { (exportSession) in
guard let session = exportSession else {
// Error
return
}
switch session.status {
case .completed:
guard NSData(contentsOf: outputURL) != nil else {
// Error
return
}

// Now you can find the video with the watermark in the location outputURL

default:
// Error
}
})

关于ios - Swift 3 : How to add watermark on video ? AVVideoCompositionCoreAnimationTool iOS 10 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40530367/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com