title: Add watermark to recorded video and save
body: <p>So I am trying to add a watermark to a previously recorded video using the following code, but when I view the video, there is no watermark. Can anyone help? I tried following the post at: <a href="https://stackoverflow.com/questions/7205820/iphone-watermark-on-recorded-video">iPhone Watermark on recorded Video.</a></p>
  
  <pre><code>    public func addWatermarkToVideo(url: NSURL, completion:(url: NSURL?) -&gt; Void) {
      let videoAsset = AVURLAsset(URL: url)
      let mixComposition = AVMutableComposition()
      let compositionVideoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
      let clipVideoTrack: AVAssetTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
      do {
          try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), ofTrack: clipVideoTrack, atTime: kCMTimeZero)
      } catch {
          print(error)
      }
  
      compositionVideoTrack.preferredTransform = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0].preferredTransform
  
      //Add watermark
      guard let myImage = UIImage(named: "Logo") else {
          completion(url: nil)
          return
      }
      let aLayer = CALayer()
      aLayer.contents = myImage.CGImage
      aLayer.frame = CGRectMake(5, 25, 100, 57)
      aLayer.opacity = 0.65
  
      let videoSize = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0].naturalSize
      let parentLayer = CALayer()
      let videoLayer = CALayer()
      parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height)
      videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height)
      parentLayer.addSublayer(videoLayer)
      parentLayer.addSublayer(aLayer)
  
      let videoComp = AVMutableVideoComposition()
      videoComp.renderSize = videoSize
      videoComp.frameDuration = CMTimeMake(1,30)
      videoComp.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, inLayer: parentLayer)
  
      let instruction = AVMutableVideoCompositionInstruction()
      instruction.timeRange = CMTimeRangeMake(kCMTimeZero, mixComposition.duration)
      let videoTrack = mixComposition.tracksWithMediaType(AVMediaTypeVideo)[0]
      let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
      instruction.layerInstructions = [layerInstruction]
      videoComp.instructions = [instruction]
  
      let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
      let documentsDirectory: AnyObject = paths[0]
      let dataPath = documentsDirectory.stringByAppendingPathComponent("VideoCache")
  
      if (!NSFileManager.defaultManager().fileExistsAtPath(dataPath)) {
          do {
              try NSFileManager.defaultManager().createDirectoryAtPath(dataPath, withIntermediateDirectories: false, attributes: nil)
          } catch {
              print("Couldn't create path")
          }
      }
      let tempURL = NSURL(fileURLWithPath: dataPath)
      let completeMovieUrl = tempURL.URLByAppendingPathComponent("tether-\(NSDate()).mov")
  
      if let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) {
          exporter.outputURL = completeMovieUrl
          exporter.outputFileType = AVFileTypeMPEG4
          exporter.exportAsynchronouslyWithCompletionHandler({ () -&gt; Void in
              switch exporter.status {
              case  .Failed:
                  print("failed \(exporter.error)")
                  completion(url: nil)
                  break
              case .Cancelled:
                  print("cancelled \(exporter.error)")
                  completion(url: nil)
                  break
              default:
                  print("complete")
                  completion(url: exporter.outputURL)
              }
          })
      }
  }
  </code></pre>