4

I've read over documentation and related questions and none seem to help my situation. I'm trying to create a *.mp4 file using AVAssetWriter from a single still image.

I can't get the asset to call it's completion block using finishWritingWithCompletionHandler:

I am keeping a strong reference to the AVAssetWriter object.

Any help or insight would be appreciated.

- (void)videoFromImage:(UIImage *)image
{
NSError *error;
self.videoWriter = [[AVAssetWriter alloc] initWithURL:
                              [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"output.mp4"]] fileType:AVFileTypeQuickTimeMovie
                                                          error:&error];
if (!error) {
    NSParameterAssert(self.videoWriter);

    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   AVVideoCodecH264, AVVideoCodecKey,
                                   [NSNumber numberWithInt:image.size.width], AVVideoWidthKey,
                                   [NSNumber numberWithInt:image.size.height], AVVideoHeightKey,
                                   nil];

    AVAssetWriterInput* videoWriterInput = [AVAssetWriterInput
                                            assetWriterInputWithMediaType:AVMediaTypeVideo
                                            outputSettings:videoSettings];


    AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
                                                     assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput
                                                     sourcePixelBufferAttributes:nil];

    NSParameterAssert(videoWriterInput);
    NSParameterAssert([self.videoWriter canAddInput:videoWriterInput]);

    [self.videoWriter addInput:videoWriterInput];
    [self.videoWriter startWriting];
    [self.videoWriter startSessionAtSourceTime:kCMTimeZero];

    if (adaptor.assetWriterInput.readyForMoreMediaData)  {
        CVPixelBufferRef buffer = [self pixelBufferFromImage:image];
        [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];
    }

    [videoWriterInput markAsFinished];

    [self.videoWriter finishWritingWithCompletionHandler:^{
        NSLog(@"finished"); // Never gets called
    }];
}
else {
    NSLog(@"%@", error.localizedDescription);
}
}

EDIT: The AVAssetWriter could not write to the file because a file with the same name already exists. Added

NSFileManager *manager = [[NSFileManager alloc] init];
if ([manager fileExistsAtPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"output.mp4"]]) {
    NSError *fileError;
    [manager removeItemAtPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"output.mp4"] error:&fileError];
    if (fileError) NSLog(@"%@", fileError.localizedDescription);
}

and it works perfectly.

Colin
  • 586
  • 4
  • 8

0 Answers0