问题
I have done image to video conversion in iphone(of course I got the code from stack overflow questions). But the problem is speed of recorded video is very fast, it ran away within 2 seconds even though I have around 2250 frames. I know the problem is with its frame rate. But i don't know how to make it correct. my code is below
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *myFilePath = [documentsDirectoryPath stringByAppendingPathComponent:@"test.mov"];
if ([self openVideoFile:myFilePath withSize:CGSizeMake (480.0, 320.0)]) {
for (int i=1; i<2226; i++) {
NSString *imagename=[NSString stringWithFormat:@"1 (%i).jpg",i];
UIImage *image=[ UIImage imageNamed:imagename];
[self writeImageToMovie:[image CGImage]];
}
[videoWriter finishWriting];
}
else {
NSLog(@"friled to open video file");
}
this code is in calling function and defenitions of the functions given below
- (BOOL) openVideoFile: (NSString *) path withSize:(CGSize)imageSize {
CGSize size = CGSizeMake (480.0, 320.0);//imageSize;
NSError *error = nil;
videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie
error:&error];
if (error != nil){
NSLog(@"error>>>> %@",error);
return NO;
}
NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:size.width], AVVideoCleanApertureWidthKey,
[NSNumber numberWithDouble:size.height], AVVideoCleanApertureHeightKey,
[NSNumber numberWithInt:10], AVVideoCleanApertureHorizontalOffsetKey,
[NSNumber numberWithInt:10], AVVideoCleanApertureVerticalOffsetKey,
nil];
NSDictionary *videoAspectRatioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:1], AVVideoPixelAspectRatioHorizontalSpacingKey,
[NSNumber numberWithInt:1],AVVideoPixelAspectRatioVerticalSpacingKey,
nil];
NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
videoCleanApertureSettings, AVVideoCleanApertureKey,
videoAspectRatioSettings, AVVideoPixelAspectRatioKey,
nil];
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
codecSettings,AVVideoCompressionPropertiesKey,
[NSNumber numberWithDouble:size.width], AVVideoWidthKey,
[NSNumber numberWithDouble:size.height], AVVideoHeightKey,
nil];
writerInput = [[AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings] retain];
NSMutableDictionary * bufferAttributes = [[NSMutableDictionary alloc] init];
[bufferAttributes setObject: [NSNumber numberWithInt: kCVPixelFormatType_32ARGB]
forKey: (NSString *) kCVPixelBufferPixelFormatTypeKey];
[bufferAttributes setObject: [NSNumber numberWithInt: 480]
forKey: (NSString *) kCVPixelBufferWidthKey];
[bufferAttributes setObject: [NSNumber numberWithInt: 320]
forKey: (NSString *) kCVPixelBufferHeightKey];
adaptor = [[AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:nil] retain];
NSMutableDictionary* attributes;
attributes = [NSMutableDictionary dictionary];
int width = 480;
int height = 320;
[attributes setObject:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
[attributes setObject:[NSNumber numberWithInt:width] forKey: (NSString*)kCVPixelBufferWidthKey];
[attributes setObject:[NSNumber numberWithInt:height] forKey: (NSString*)kCVPixelBufferHeightKey];
CVReturn theError = CVPixelBufferPoolCreate(kCFAllocatorDefault, NULL, (CFDictionaryRef) attributes, &pixelBufferPool);
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
writerInput.expectsMediaDataInRealTime = YES;
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
buffer = NULL;
lastTime = kCMTimeZero;
presentTime = kCMTimeZero;
return YES;
}
- (void) writeImageToMovie:(CGImageRef)image
{
if([writerInput isReadyForMoreMediaData])
{
buffer = [self pixelBufferFromCGImage:image];
BOOL success = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
if (!success) NSLog(@"Failed to appendPixelBuffer");
CVPixelBufferRelease(buffer);
presentTime = CMTimeAdd(lastTime, CMTimeMake(1, 1000));//I think problem is here but what will be given for correct output
lastTime = presentTime;
}
else
{
NSLog(@"error - writerInput not ready");
}
}
- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image
{
CGSize size = CGSizeMake (480.0, 320.0);
CVPixelBufferRef pxbuffer;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
if (pixelBufferPool == NULL) NSLog(@"pixelBufferPool is null!");
CVReturn status = CVPixelBufferPoolCreatePixelBuffer (NULL, pixelBufferPool, &pxbuffer);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
size.height, 8, 4*size.width, rgbColorSpace,
kCGImageAlphaNoneSkipFirst);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(90, 10, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
What to do with the CMTime variables and how can I made it correctly One more help how can I add audio with this video.
回答1:
Your PTSs are very close together. Instead of CMTimeMake(1, 1000)
, why not 30FPS: CMTimeMake(1, 30))
?
回答2:
I revised you code and came up to the solution, in my case I record every image in my view in 0.1 seconds so my fps is 0.1fps.
presentTime = CMTimeAdd(lastTime, CMTimeMake(1, 10));
The reason why your video is too fast because your ratio is 1 seconds into 1000 image. You can make it 1 image per second.
presentTime = CMTimeAdd(lastTime, CMTimeMake(1, 1));
Try this out, hope it will help you.
回答3:
Add this library AVFoundation CoreMedia CoreVideo
i am able to generate video , but not able to get audio is anyone had use this code and create video with audio
来源:https://stackoverflow.com/questions/8497481/iphone-image-to-video-issue-in-video-speed