title: Swift 3: How to add watermark on video ? AVVideoCompositionCoreAnimationTool iOS 10 issue
body: <p>This code used to work on iOS9 to add a watermark and text to a video but since iOS10 it's not working anymore. There is a <a href="https://stackoverflow.com/questions/39745570/avassetexportsession-in-ios-10-not-working-for-iphone-7/39746140#39746140/" title="iOS 10 bug">iOS 10 bug</a> that has been filed but no answer from Apple. I have not been able to implement any workaround to add watermark and text on video. With this code some times the video will be exported successfully but most of time it won't be exported.</p>
  
  <p>How should I use <code>AVVideoCompositionCoreAnimationTool</code> so that it works as it did on iOS9.    </p>
  
  <pre><code>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()
          }
  
      }
  
  })
  </code></pre>
  
  <p>PLEASE NOTE: If I remove <code>AVVideoCompositionCoreAnimationTool</code> then the video is always exported but this ,hans no watermark and text on video. How to make it work so that <code>AVVideoCompositionCoreAnimationTool</code> does not conflict with <code>AVAssetExportSession</code> ?</p>
  
  <p>Some have implemented a <a href="https://stackoverflow.com/questions/39760147/ios-10-avplayerlayer-doesnt-show-video-after-using-avvideocompositioncoreanima/39780044#39780044/" title="workaound">workaround</a> with <code>customVideoCompositorClass</code> and <code>AVVideoCompositing</code> protocol but this seems to be a heavy workaround compared to how it used to work.</p>