title: Problem setting video frame rate using AVAssetWriter/AVAssetReader
body: <h2>Situation:</h2>
  <p>I am trying to export video with some parameters like video bit rate, audio bit rate, frame rate, changing video resolution, etc. Note that I am letting the user set the video frame rate in fractions; like user can set the video frame rate say, 23.98.</p>
  <p>I use <strong>AVAssetWriter</strong> and <strong>AVAssetReader</strong> for this operation. I use <a href="https://developer.apple.com/documentation/avfoundation/avassetwriterinputpixelbufferadaptor" rel="noreferrer">AVAssetWriterInputPixelBufferAdaptor</a> for writing the sample buffers.</p>
  <p>Everything else works just fine, except the <strong>video frame rate</strong>.</p>
  <h2>What I have tried:</h2>
  <ol>
  <li>Setting the <strong>AVAssetWriter.movieTimeScale</strong> as suggested <a href="https://stackoverflow.com/a/16911799/1208191">here</a>. Which does change the video frame rate but also makes the video sluggish. (<a href="https://gist.github.com/chauhan130/31b8bf648f0071a949d1627c78315056#file-gistfile1-txt-L16" rel="noreferrer">gist here</a>)</li>
  </ol>
  <hr />
  <ol start="2">
  <li>Setting <strong>AVVideoExpectedSourceFrameRateKey</strong>. Which does not help. (<a href="https://gist.github.com/chauhan130/31b8bf648f0071a949d1627c78315056#file-gistfile1-txt-L38" rel="noreferrer">gist here</a>)</li>
  </ol>
  <hr />
  <ol start="3">
  <li>Setting <strong>AVAssetWriterInput.mediaTimeScale</strong>. Again, it changes the video frame rate but makes the video sluggish as <em>AVAssetWriter.movieTimeScale</em> does. The video shows different frames at some point and sometimes it sticks and resumes again. (<a href="https://gist.github.com/chauhan130/31b8bf648f0071a949d1627c78315056#file-gistfile1-txt-L50" rel="noreferrer">gist here</a>)</li>
  </ol>
  <hr />
  <ol start="4">
  <li>Using <strong>AVAssetReaderVideoCompositionOutput</strong> and setting <strong>AVMutableVideoComposition.frameDuration</strong>; just like <a href="https://github.com/rs/SDAVAssetExportSession" rel="noreferrer">SDAVAssetExportSession</a> does. Ironically with SDAVAssetExportSession code, the video is being exported just at the right frame rate that I want, but it just does not work in my code. <a href="https://gist.github.com/chauhan130/8d2f5bbe680353961fecacb80e254b92#file-gistfile1-txt-L77" rel="noreferrer">gist here</a></li>
  </ol>
  <p>I am not sure why it won't work with my code. The issue with this approach is it always returns nil from <em>AVAssetReaderVideoCompositionOutput.copyNextSampleBuffer()</em>.</p>
  <hr />
  <ol start="5">
  <li>Manually changing the timestamp of the frame with <strong>CMSampleTimingInfo</strong>, as suggested <a href="https://stackoverflow.com/a/49236475/1208191">here</a> Something like:</li>
  </ol>
  <pre><code>var sampleTimingInfo = CMSampleTimingInfo()
  var sampleBufferToWrite: CMSampleBuffer?
  
  CMSampleBufferGetSampleTimingInfo(vBuffer, at: 0, timingInfoOut: &amp;sampleTimingInfo)
  
  sampleTimingInfo.duration = CMTimeMake(value: 100, timescale: Int32(videoConfig.videoFrameRate * 100))
  
  sampleTimingInfo.presentationTimeStamp = CMTimeAdd(previousPresentationTimeStamp, sampleTimingInfo.duration)
  
  previousPresentationTimeStamp = sampleTimingInfo.presentationTimeStamp
  
  let status = CMSampleBufferCreateCopyWithNewTiming(allocator: kCFAllocatorDefault, sampleBuffer: vBuffer,sampleTimingEntryCount: 1, sampleTimingArray: &amp;sampleTimingInfo, sampleBufferOut: &amp;sampleBufferToWrite)
  </code></pre>
  <p>With this approach, I do get the frame rate set just right, but it increases the video duration (as mentioned in the comment of that question’s answer). I think at some point I may have to discard some frames (if the target frame rate is lower; I need to lower the frame rate in most of the cases).</p>
  <p>If I know that if I want 30fps, and my current frame rate is 60fps, it's simple to discard every second frame and setting the SampleBuffer time accordingly.</p>
  <p>If I go with this approach(i.e. setting 23.98 fps), how do I decide which frame to discard and if the target frame rate is higher, which frame to duplicate? Reminder: the frame rate could be in fractions.</p>
  <hr />