【发布时间】:2016-10-06 08:37:50
【问题描述】:
以下代码可以完美地使用 AVVideoCompositionCoreAnimationTool 将徽标和文本添加到视频中。然后 Swift 3 来了!现在有时视频显示带有徽标和文字,有时视频在导出时不显示。
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()
}
}
})
这在以前版本的 Swift 中可以正常工作,但现在 swift 3 不再工作了。
请注意:如果我注释掉videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer),则视频将被导出并成功超时播放,但没有任何覆盖。
【问题讨论】:
-
NSArray(object: transformer)中的transformer是什么?你试过在 iOS9 设备上运行代码吗? -
@RhythmicFistman 我编辑了关于变压器的问题。你对 iOS9 设备提出了一个很好的观点,事实上我刚刚在 iOS9 设备上进行了尝试,它似乎工作得很好。你为什么问iOS9设备?您认为这是与 iOS10 相关的问题吗?非常感谢:)
-
我问是因为 iOS 10 中似乎存在
AVAssetExportSessions 和视频合成的错误。 stackoverflow.com/a/39605744/22147 除了等待iOS 10.1 stackoverflow.com/a/39746140/22147,还有一些变通方法:stackoverflow.com/a/39780044/22147 -
@RhythmicFistman 好的,非常感谢您的帮助!如果您想回答,我可以将其标记为正确答案,欢迎您。谢谢! :)
-
有没有办法分享完整的代码?我正在寻找
clipVideoTrack和asset
标签: swift video avfoundation core-animation overlay