質問

This code works for creating video from images. AVAssetWritter work fine without error and export output video - (.mov). But it fail in some case of image size. 120 x 160 - fail 180 x 640 , 240 x 320, 160 x 213.333, 96 x 128 - pass

P/s: Test on iPod 4th ios 5.1

This is screenshot http://postimg.org/image/gih1ofvbn/ of fail video for size 120 x 160, please help me solve this issue. Or any recommend for other video encoder library will be welcome. Thanks

This is my code

- (void) writeImagesAsMovie:(NSArray *)images withDelaySec:(float)delaySec toPath:(NSString*)path   {
//delete file
NSFileManager *fileMgr = [[NSFileManager alloc] init];
NSError *error2;
if ([fileMgr removeItemAtPath:path error:&error2] != YES)
    NSLog(@"Unable to delete file: %@", [error2 localizedDescription]);


UIImage *first = [images objectAtIndex:0];


CGSize frameSize = first.size;
NSLog(@"__create video: %f %f", frameSize.width, frameSize.height);

NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
                              [NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie
                                                          error:&error];

if(error) {
    NSLog(@"error creating AssetWriter: %@",[error description]);
}

int numPixels = frameSize.width * frameSize.height;
int bitsPerSecond;
float bitsPerPixel;
// Assume that lower-than-SD resolutions are intended for streaming, and use a lower bitrate
if ( numPixels < (640 * 480) )
    bitsPerPixel = 4.05; // This bitrate matches the quality produced by AVCaptureSessionPresetMedium or Low.
else
    bitsPerPixel = 11.4; // This bitrate matches the quality produced by AVCaptureSessionPresetHigh.

bitsPerSecond = numPixels * bitsPerPixel;

NSDictionary *videoCompressionSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                          AVVideoCodecH264, AVVideoCodecKey,
                                          [NSNumber numberWithInteger:frameSize.width], AVVideoWidthKey,
                                          [NSNumber numberWithInteger:frameSize.height], AVVideoHeightKey,
                                          [NSDictionary dictionaryWithObjectsAndKeys:
                                           [NSNumber numberWithInteger:bitsPerSecond], AVVideoAverageBitRateKey,
                                           [NSNumber numberWithInteger:30], AVVideoMaxKeyFrameIntervalKey,
                                           nil], AVVideoCompressionPropertiesKey,
                                          nil];
AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoCompressionSettings];

writerInput.expectsMediaDataInRealTime = YES;

NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey];


AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
                                                 assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
                                                 sourcePixelBufferAttributes:attributes];

[videoWriter addInput:writerInput];

// fixes all errors
writerInput.expectsMediaDataInRealTime = YES;

//Start a session:
[videoWriter startWriting];

[videoWriter startSessionAtSourceTime:kCMTimeZero];

CVPixelBufferRef buffer = NULL;
buffer = [self pixelBufferFromCGImage:[first CGImage]];
BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];

if (result == NO) //failes on 3GS, but works on iphone 4
    NSLog(@"failed to append buffer");

if(buffer) {
    CVBufferRelease(buffer);
}


float delayMili = delaySec * 25;
int fps = 30;


int i = 0;
for (UIImage *imgFrame in images)
{
    if (adaptor.assetWriterInput.readyForMoreMediaData) {

        i++;
        CMTime frameTime = CMTimeMake(delayMili, fps);
        CMTime lastTime = CMTimeMake(delayMili * i, fps);
        CMTime presentTime = CMTimeAdd(lastTime, frameTime);

        NSLog(@"__presentTime: %f", CMTimeGetSeconds(presentTime));

        buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]];
        BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];

        if (result == NO) //failes on 3GS, but works on iphone 4
        {
            NSLog(@"failed to append buffer");
            NSLog(@"The error is %@", [videoWriter error]);
        }

        if(buffer) {
            CVBufferRelease(buffer);
        }

    } else {
        NSLog(@"error");
        i--;
    }

}

//Finish the session:
[writerInput markAsFinished];
[videoWriter finishWriting];
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
[videoWriter release];
[writerInput release];

NSLog(@"Movie created successfully");

}

役に立ちましたか?

解決

The width of the video should be divisible by 16.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top