Swift 3:AVVideoCompositionCoreAnimationTool在视频上添加水印的问题

时间:2016-10-06 08:37:50

标签: swift video avfoundation core-animation overlay

以下代码完美地使用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),那么视频会被导出并成功播放,但没有任何叠加。

1 个答案:

答案 0 :(得分:1)

看到代码适用于iOS 9,这可能是a bug in iOS 10.0 AVAssetExportSessions videoComposition设置@Rahul时无法正常工作。

有些人报告iOS 10.1 beta内的情况看起来更好,其他人worked around the problem