title: Compressing and encoding an AVAsset to mp4
body: <p>I am trying to compress an <code>AVAsset</code> to lower quality and then export it as an mp4. The input asset could be any type of video that the camera roll allows. </p>
  
  <p>The problem I am running into is that when I try to export an asset to <code>AVAssetExportPresetMediumQuality</code> it fails at the first guard statement when the input is a mp4 file originally. However if I change it to <code>AVAssetExportPresetPassthrough</code> it works but doesn't compress the file. Is there a one way solution to compressing/encoding an asset that could be a .mov or .mp4 originally?</p>
  
  <pre><code>func encodeVideo(asset: AVAsset, completionHandler: @escaping (URL?, String?) -&gt; ())  {
      guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
          completionHandler(nil, nil)
          return
      }
      let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL
      let filePath = documentsDirectory.appendingPathComponent("compressed-video.mp4")
      if FileManager.default.fileExists(atPath: filePath.path) {
          do {
              try FileManager.default.removeItem(at: filePath)
          } catch {
              completionHandler(nil, nil)
          }
      }
      exportSession.outputURL = filePath
      exportSession.outputFileType = .mp4
      exportSession.shouldOptimizeForNetworkUse = true
      let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
      let range = CMTimeRangeMake(start: start, duration: asset.duration)
      exportSession.timeRange = range
  
      exportSession.exportAsynchronously {
          switch exportSession.status {
          case .failed:
              print("Conversion Failed")
              completionHandler(nil, exportSession.error?.localizedDescription)
          case .cancelled:
              print("Conversion Cancelled")
              completionHandler(nil, exportSession.error?.localizedDescription)
          case .completed:
              completionHandler(exportSession.outputURL, nil)
              default: break
          }
      }
  }
  </code></pre>