Cutting MPEG-TS file via ffmpegwrapper?
<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>