AVAssetWriterInputPixelBufferAdaptor appendPixelBuffer:buffer withPresentationTime returning error NSURLErrorCannotCreateFile

Viewed 1334

I am creating a video file from an array of images. I am able to create video file on simulator, however when I try to run the same code on device it gives following error:

NSURLErrorDomain Code=-3000 "Cannot create file" UserInfo=0x200be260 {NSUnderlyingError=0x200bb030 "The operation couldn’t be completed. (OSStatus error -12149.)", NSLocalizedDescription=Cannot create file}

I have searched a lot but couldn't find anything.

Here is the code for creating path.

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/movie.mp4"]];


-(void)exportImages:(NSArray *)imageArray
      asVideoToPath:(NSString *)path
      withFrameSize:(CGSize)imageSize
    framesPerSecond:(NSUInteger)fps {

NSLog(@"Start building video from defined frames.");

NSError *error = nil;

NSURL *url = [NSURL fileURLWithPath:path];

AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
                              url fileType:AVFileTypeMPEG4
                                                          error:&error];
NSParameterAssert(videoWriter);

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

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


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

NSParameterAssert(videoWriterInput);
NSParameterAssert([videoWriter canAddInput:videoWriterInput]);
videoWriterInput.expectsMediaDataInRealTime = YES;
[videoWriter addInput:videoWriterInput];

//Start a session:
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];

CVPixelBufferRef buffer = NULL;

//convert uiimage to CGImage.
int frameCount = 0;

for(UIImage * img in imageArray) {
    buffer = [self pixelBufferFromCGImage:[img CGImage] andSize:imageSize];

    while (1) {
        if (adaptor.assetWriterInput.readyForMoreMediaData) {
            break;
        }
    }

    BOOL append_ok = NO;
    int j = 0;
    while (!append_ok && j < 30) {
        NSString *border = @"**************************************************";
        NSLog(@"\n%@\nProcessing video frame (%d,%d).\n%@",border,frameCount,[imageArray count],border);

        CMTime frameTime = CMTimeMake(frameCount,(int32_t) fps);
        append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
        if(!append_ok){
            NSError *error = videoWriter.error;
            if(error!=nil) {
                NSLog(@"Unresolved error %@,%@.", error, [error userInfo]);
            }
        }
        j++;
    }
    if (!append_ok) {
        printf("error appending image %d times %d\n, with error.", frameCount, j);
    }
    frameCount++;
}

//Finish the session:
[videoWriterInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^{
    NSLog(@"Write Ended");
}];

}

1 Answers
Related