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.