title: Cutting MPEG-TS file via ffmpegwrapper?
body: <p>I have MPEG-TS files on the device. I would like to cut a fairly-exact time off the start of the files on-device.</p>
  
  <p>Using <a href="https://github.com/OpenWatch/FFmpegWrapper" rel="nofollow noreferrer">FFmpegWrapper</a> as a base, I'm hoping to achieve this. </p>
  
  <p>I'm a little lost on the C API of ffmpeg, however. Where do I start?</p>
  
  <p>I tried just dropping all packets prior to a start PTS I was looking for, but this broke the video stream.</p>
  
  <pre><code>    packet-&gt;pts = av_rescale_q(packet-&gt;pts, inputStream.stream-&gt;time_base, outputStream.stream-&gt;time_base);
      packet-&gt;dts = av_rescale_q(packet-&gt;dts, inputStream.stream-&gt;time_base, outputStream.stream-&gt;time_base);
  
      if(startPts == 0){
          startPts = packet-&gt;pts;
      }
  
      if(packet-&gt;pts &lt; cutTimeStartPts + startPts){
          av_free_packet(packet);
          continue;
      }
  </code></pre>
  
  <p>How do I cut off part of the start of the input file without destroying the video stream? When played back to back, I want 2 cut segments to run seamlessly together.</p>
  
  <pre><code>ffmpeg -i time.ts -c:v libx264 -c:a copy -ss $CUT_POINT -map 0 -y after.ts
  ffmpeg -i time.ts -c:v libx264 -c:a copy -to $CUT_POINT -map 0 -y before.ts
  </code></pre>
  
  <p>Seems to be what I need. I think the re-encode is needed so the video can start at any arbitrary point and not an existing keyframe. If there's a more efficient solution, that's great. If not, this is good enough.</p>
  
  <p>EDIT: Here's my attempt. I'm cobbling together various pieces I don't fully understand copied from <a href="https://stackoverflow.com/questions/20856803/how-to-cut-video-with-ffmpeg-c-api">here</a>. I'm leaving off the "cutting" piece for now to try and get audio + video encoded written without layering complexity. I get EXC_BAD_ACCESS on <code>avcodec_encode_video2(...)</code></p>
  
  <pre><code>- (void)convertInputPath:(NSString *)inputPath outputPath:(NSString *)outputPath
                   options:(NSDictionary *)options progressBlock:(FFmpegWrapperProgressBlock)progressBlock
           completionBlock:(FFmpegWrapperCompletionBlock)completionBlock {
      dispatch_async(conversionQueue, ^{
          FFInputFile *inputFile = nil;
          FFOutputFile *outputFile = nil;
          NSError *error = nil;
  
          inputFile = [[FFInputFile alloc] initWithPath:inputPath options:options];
          outputFile = [[FFOutputFile alloc] initWithPath:outputPath options:options];
  
          [self setupDirectStreamCopyFromInputFile:inputFile outputFile:outputFile];
          if (![outputFile openFileForWritingWithError:&amp;error]) {
              [self finishWithSuccess:NO error:error completionBlock:completionBlock];
              return;
          }
          if (![outputFile writeHeaderWithError:&amp;error]) {
              [self finishWithSuccess:NO error:error completionBlock:completionBlock];
              return;
          }
  
          AVRational default_timebase;
          default_timebase.num = 1;
          default_timebase.den = AV_TIME_BASE;
          FFStream *outputVideoStream = outputFile.streams[0];
          FFStream *inputVideoStream = inputFile.streams[0];
  
          AVFrame *frame;
          AVPacket inPacket, outPacket;
  
          frame = avcodec_alloc_frame();
          av_init_packet(&amp;inPacket);
  
          while (av_read_frame(inputFile.formatContext, &amp;inPacket) &gt;= 0) {
              if (inPacket.stream_index == 0) {
                  int frameFinished;
                  avcodec_decode_video2(inputVideoStream.stream-&gt;codec, frame, &amp;frameFinished, &amp;inPacket);
  //                if (frameFinished &amp;&amp; frame-&gt;pkt_pts &gt;= starttime_int64 &amp;&amp; frame-&gt;pkt_pts &lt;= endtime_int64) {
                  if (frameFinished){
                      av_init_packet(&amp;outPacket);
                      int output;
                      avcodec_encode_video2(outputVideoStream.stream-&gt;codec, &amp;outPacket, frame, &amp;output);
                      if (output) {
                          if (av_write_frame(outputFile.formatContext, &amp;outPacket) != 0) {
                              fprintf(stderr, "convert(): error while writing video frame\n");
                              [self finishWithSuccess:NO error:nil completionBlock:completionBlock];
                          }
                      }
                      av_free_packet(&amp;outPacket);
                  }
                  if (frame-&gt;pkt_pts &gt; endtime_int64) {
                      break;
                  }
              }
          }
          av_free_packet(&amp;inPacket);
  
          if (![outputFile writeTrailerWithError:&amp;error]) {
              [self finishWithSuccess:NO error:error completionBlock:completionBlock];
              return;
          }
  
          [self finishWithSuccess:YES error:nil completionBlock:completionBlock];
      });
  }
  </code></pre>