Search code examples
iosobjective-cvideoavfoundationavassetwriter

Captured video with AVAssetWriter have duration zero


I'm trying to capture video with AVAssetWriter, AVCaptureSession, AVCaptureOutput and AVAssetWriterInput.

Here is delegate method for AVCaptureOutput where I'm adding buffers:

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {


    if (self.assetWriter.status != AVAssetWriterStatusWriting) {

        CMTime startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);

        [self.assetWriter startWriting];

        [self.assetWriter startSessionAtSourceTime:startTime];
    }
    if ([captureOutput isKindOfClass:AVCaptureVideoDataOutput.class] && self.videoWriterInput.isReadyForMoreMediaData) {

        [self.videoWriterInput appendSampleBuffer:sampleBuffer];
    }
    else if ([captureOutput isKindOfClass:AVCaptureAudioDataOutput.class] && self.audioWriterInput.isReadyForMoreMediaData) {

        [self.audioWriterInput appendSampleBuffer:sampleBuffer];
    }
}

And method for finishing writing:

- (void)finishCurrentWriting {

    [self.videoWriterInput markAsFinished];
    [self.audioWriterInput markAsFinished];

    __weak ViewController *weakSelf = self;

    [self.assetWriter finishWritingWithCompletionHandler:^{

        dispatch_async(dispatch_get_main_queue(), ^{

            [weakSelf runVideo];
        });
    }]; 
}

When I'm ending writing video into file, I'm trying to play it via MPMoviePlayerController. The data is available because file have significant size, but for some reasons, the duration of video is zero. What am I doing wrong?

Added repository with test code. It is for HLS streaming, so for now it should make 15s videos and after that display it in player on bottom of screen(now player is just black, and video duration is 0).


Solution

  • Make sure to call [AVAssetWriter finishWritingWithCompletionHandler:] when you've finished.

    You should be calling startSessionAtSourceTime with presentation time stamp of the first buffer you receive.

    You can delete the [self.assetWriter endSessionAtSourceTime:kCMTimeZero]; .