ASSETWriterInput for making Video from UIImages on Iphone Issues

1)Adaptor class

AVAssetWriterInputPixelBufferAdaptor * avAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterI nput:writerInput sourcePixelBufferAttributes:NULL]; [avAdaptor appendPixelBufferixelBuffer withPresentationTime:CMTimeMake(1, 10)]; 

2)Making the

// Create sample buffer. CMSampleBufferRef sampleBuffer = NULL; result = CMSampleBufferCreateForImageBuffer(kCFAllocatorDef ault, pixelBuffer, true, NULL, NULL, videoInfo, &timing, &sampleBuffer); // Ship out the frame. NSParameterAssert(CMSampleBufferDataIsReady(sample Buffer)); NSParameterAssert([writerInput isReadyForMoreMediaData]); BOOL success = [writerInput appendSampleBuffer:sampleBuffer]; 
share | edit

62% accept rate
 
feedback

1 Answer

active oldest votes
up vote 8 down vote

I found that for some reason I needed to append the buffer more than once. The timing in this example from a test app I made might not be proper, but since it works it should give you a good idea.

+ (void)writeImageAsMovie:(UIImage*)image toPath:(NSString*)path size:(CGSize)size duration:(int)duration {     NSError *error = nil;     AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:                                   [NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie                                                               error:&error];     NSParameterAssert(videoWriter);     NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:                                    AVVideoCodecH264, AVVideoCodecKey,                                    [NSNumber numberWithInt:size.width], AVVideoWidthKey,                                    [NSNumber numberWithInt:size.height], AVVideoHeightKey,                                    nil];     AVAssetWriterInput* writerInput = [[AVAssetWriterInput                                         assetWriterInputWithMediaType:AVMediaTypeVideo                                         outputSettings:videoSettings] retain];     AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor                                                      assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput                                                      sourcePixelBufferAttributes:nil];     NSParameterAssert(writerInput);     NSParameterAssert([videoWriter canAddInput:writerInput]);     [videoWriter addInput:writerInput];     //Start a session:     [videoWriter startWriting];     [videoWriter startSessionAtSourceTime:kCMTimeZero];     //Write samples:     CVPixelBufferRef buffer = [Utils pixelBufferFromCGImage:image.CGImage size:size];     [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];     [adaptor appendPixelBuffer:buffer withPresentationTime:CMTimeMake(duration-1, 2)];     //Finish the session:     [writerInput markAsFinished];     [videoWriter endSessionAtSourceTime:CMTimeMake(duration, 2)];     [videoWriter finishWriting]; } 

This method is not required, but is used here as an example of a pixel buffer source:

+ (CVPixelBufferRef) pixelBufferFromCGImage:(CGImageRef)image size:(CGSize)size {     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:                              [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,                              [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,                              nil];     CVPixelBufferRef pxbuffer = NULL;     CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, size.width,                           size.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,                           &pxbuffer);     status=status;//Added to make the stupid compiler not show a stupid warning.     NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);     CVPixelBufferLockBaseAddress(pxbuffer, 0);     void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);     NSParameterAssert(pxdata != NULL);     CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();     CGContextRef context = CGBitmapContextCreate(pxdata, size.width,                                                  size.height, 8, 4*size.width, rgbColorSpace,                                                  kCGImageAlphaNoneSkipFirst);     NSParameterAssert(context);     //CGContextTranslateCTM(context, 0, CGImageGetHeight(image));     //CGContextScaleCTM(context, 1.0, -1.0);//Flip vertically to account for different origin     CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),                                          CGImageGetHeight(image)), image);     CGColorSpaceRelease(rgbColorSpace);     CGContextRelease(context);     CVPixelBufferUnlockBaseAddress(pxbuffer, 0);     return pxbuffer; } 
share | edit
 
excellent it worked. that double commands are bugs? anyway, any ideas how to add audio to that video as well. I am using AvAudioPlayer. –  lilzz Oct 22 '10 at 1:26
 
You can make an AVMutableComposition and insert your audio and video into the composition. If you want to fade, etc., you can use an AVMutableAudioMix. The composition and audioMix can be added to your AVPlayerItem for your player. –  Peter DeWeese Oct 22 '10 at 13:04
1  
I also discovered you have to append the buffer twice -- at least, I haven't figure out how to make it work without this kludge. Anyone know why this is necessary? –  John Sep 21 '11 at 19:52
 
Will it work without implementing above method?And what to pass in duration parameter ? –  Born Survivor Jul 9 at 5:21
 
@iApple: take duration in int..like int duration=10; :) –  iPhone Developer Jul 31 at 6:31

你可能感兴趣的:(ASSETWriterInput for making Video from UIImages on Iphone Issues)