title: Compressing Video using HEVC Codec with swift 4
body: <p>Apple is using a new video codec hevc and i am trying to compress videos with my application using the hevc codec. For some reason the app just crashes and returns the file size as 0 mb. It works when i compress it using H264, however when I use H265(HEVC), the app just crashes. This is my code. </p>
  
  <p>I am assuming there is something wrong with the way i am outputting the file. For right now, I am using an mov file. Should i be using another type of file extension for the specific HEVC codec. I am not too sure what is going on here.</p>
  
  <pre><code>func compressFile(urlToCompress: URL, completion:@escaping (URL)-&gt;Void){
      //video file to make the asset
  
      var audioFinished = false
      var videoFinished = false
  
  
  
      let asset = AVAsset(url: urlToCompress)
  
      //create asset reader
      do{
          assetReader = try AVAssetReader(asset: asset)
      } catch{
          assetReader = nil
      }
  
      guard let reader = assetReader else{
          fatalError("Could not initalize asset reader probably failed its try catch")
      }
  
      let videoTrack = asset.tracks(withMediaType: AVMediaType.video).first!
      let audioTrack = asset.tracks(withMediaType: AVMediaType.audio).first!
  
      let videoReaderSettings: [String:Any] = [kCVPixelBufferPixelFormatTypeKey as String!:kCVPixelFormatType_32ARGB]
  
      // ADJUST BIT RATE OF VIDEO HERE
  
      let videoSettings:[String:Any] = [
          AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey:self.bitrate],
          AVVideoCodecKey: AVVideoCodecType.hevc,
          AVVideoHeightKey: videoTrack.naturalSize.height,
          AVVideoWidthKey: videoTrack.naturalSize.width
      ]
  
  
      let assetReaderVideoOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
      let assetReaderAudioOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil)
  
  
      if reader.canAdd(assetReaderVideoOutput){
          reader.add(assetReaderVideoOutput)
      }else{
          fatalError("Couldn't add video output reader")
      }
  
      if reader.canAdd(assetReaderAudioOutput){
          reader.add(assetReaderAudioOutput)
      }else{
          fatalError("Couldn't add audio output reader")
      }
  
      let audioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: nil)
      let videoInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
      videoInput.transform = videoTrack.preferredTransform
      //we need to add samples to the video input
  
      let videoInputQueue = DispatchQueue(label: "videoQueue")
      let audioInputQueue = DispatchQueue(label: "audioQueue")
      let formatter = DateFormatter()
      formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
      let date = Date()
      let documentsPath = NSTemporaryDirectory()
      let outputPath = "\(documentsPath)/\(formatter.string(from: date)).mov"
      let newOutputUrl = URL(fileURLWithPath: outputPath)
  
      do{
          assetWriter = try AVAssetWriter(outputURL: newOutputUrl, fileType: AVFileType.mov)
      }catch{
          assetWriter = nil
      }
      guard let writer = assetWriter else{
          fatalError("assetWriter was nil")
      }
  
      writer.shouldOptimizeForNetworkUse = true
      writer.add(videoInput)
      writer.add(audioInput)
  
  
      writer.startWriting()
      reader.startReading()
      writer.startSession(atSourceTime: kCMTimeZero)
  
  
      let closeWriter:()-&gt;Void = {
          if (audioFinished &amp;&amp; videoFinished){
              self.assetWriter?.finishWriting(completionHandler: {
  
                  self.checkFileSize(sizeUrl: (self.assetWriter?.outputURL)!, message: "The file size of the compressed file is: ")
                  completion((self.assetWriter?.outputURL)!)
                  print("Completed 1")
  
              })
  
              self.assetReader?.cancelReading()
  
          }
      }
  
  
      audioInput.requestMediaDataWhenReady(on: audioInputQueue) {
          while(audioInput.isReadyForMoreMediaData){
              let sample = assetReaderAudioOutput.copyNextSampleBuffer()
              if (sample != nil){
                  audioInput.append(sample!)
              }else{
                  audioInput.markAsFinished()
                  DispatchQueue.main.async {
                      audioFinished = true
                      closeWriter()
                      print("Completed 2")
                  }
                  break;
              }
          }
      }
  
      videoInput.requestMediaDataWhenReady(on: videoInputQueue) {
          //request data here
  
          while(videoInput.isReadyForMoreMediaData){
              let sample = assetReaderVideoOutput.copyNextSampleBuffer()
              if (sample != nil){
                  videoInput.append(sample!)
              }else{
                  videoInput.markAsFinished()
                  DispatchQueue.main.async {
                      videoFinished = true
                      print("Completed 3")
                      closeWriter()
                  }
                  break;
              }
          }
  
      }
  
  
  }
  
  func checkFileSize(sizeUrl: URL, message:String){
      let data = NSData(contentsOf: sizeUrl)!
      print(message, (Double(data.length) / 1048576.0), " mb")
  }
  </code></pre>