Swift 3:AVVideoCompositionCoreAnimationTool问题在视频上添加水印 [英] Swift 3 : issue with AVVideoCompositionCoreAnimationTool to add watermark on video

查看:112
本文介绍了Swift 3:AVVideoCompositionCoreAnimationTool问题在视频上添加水印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码可以完美地使用AVVideoCompositionCoreAnimationTool向视频添加徽标和文本.然后Swift 3来了!现在,有时视频显示带有徽标和文本,有时视频在导出时不显示.

The following code was working perfectly to add a logo and a text to a video with AVVideoCompositionCoreAnimationTool. Then Swift 3 came! Now sometimes the video shows with the logo and text sometimes the video does not show when it is exported.

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上不再可以使用了.

This was working flawlessly with previous version of Swift but now with swift 3 not working anymore.

请注意:如果我将videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)注释掉,则视频将被导出,并且可以成功超时播放,但没有任何覆盖.

PLEASE NOTE: if I comment out videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer) then the video is exported and plays successfully overtime but without any overlay.

推荐答案

看到该代码可在iOS 9上运行,这可能是 a iOS 10.0中的错误,其中设置了videoCompositionAVAssetExportSessions无法正常工作.

Seeing as the code works on iOS 9, this is probably a bug in iOS 10.0 where AVAssetExportSessions don't work properly when they have videoComposition set.

有些人报告说,在 iOS 10.1 beta 中,情况看起来更好,而其他人则具有

Some have reported that things look better in the iOS 10.1 beta and others have worked around the problem.

这篇关于Swift 3:AVVideoCompositionCoreAnimationTool问题在视频上添加水印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆