views:

36

answers:

1

I try the following 2 methods of appending UIIMages pixelbuffer to ASSETWriterInput. Everything looks good except there's No data in the video file. What's wrong?

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];
+1  A: 

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];
}
Peter DeWeese
excellent it worked. that double commands are bugs? anyway, any ideas how to add audio to that video as well. I am using AvAudioPlayer.
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