0
我正在嘗試創建視頻文件的圖像文件。我在NSArray中設置圖像文件的名稱。當圖像文件的數量很大(超過80或100)時,我收到內存警告,有時應用程序崩潰。這是我的代碼:從圖像陣列創建mp4視頻時的內存警告
-(void)writeImageAsMovie:(NSArray *)images toPath:(NSString*)path size:(CGSize)size duration:(int)duration
{
NSError *error = nil;
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] ;
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:nil];
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
//Start a session:
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:CMTimeMake(0, 1000)];
CVPixelBufferRef buffer = NULL;
//convert uiimage to CGImage.
//Write samples:
for (int i=0; i<images.count ; i++) {
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfFile:[[images objectAtIndex:i] objectForKey:@"image"]]];
int time = [[[images objectAtIndex:i] objectForKey:@"time"] intValue];
buffer = [self pixelBufferFromCGImage:image.CGImage];
while(! adaptor.assetWriterInput.readyForMoreMediaData);
[adaptor appendPixelBuffer:buffer withPresentationTime:CMTimeMake(time,1000)];
image=nil;
}
while(!adaptor.assetWriterInput.readyForMoreMediaData);
//Finish the session:
[writerInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^(){
NSLog (@"finished writing %d",images.count);
}];
NSLog(@"%d",[videoWriter status]);
while([videoWriter status] != AVAssetWriterStatusFailed && [videoWriter status] != AVAssetWriterStatusCompleted) {
NSLog(@"Status: %d", [videoWriter status]);
sleep(1);
}
NSLog(@"%d",[videoWriter status]);
NSString *tmpdir = NSTemporaryDirectory();
NSString *mydir = [tmpdir stringByAppendingPathComponent:@"vidimages"];
[[NSFileManager defaultManager] removeItemAtPath:mydir error:nil];
}
- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
{
CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, screenWidth,
screenWidth, kCVPixelFormatType_32BGRA, (__bridge CFDictionaryRef) options,
&pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context1 = CGBitmapContextCreate(pxdata, screenWidth,
screenWidth, 8, 4*screenWidth, rgbColorSpace,
kCGImageAlphaNoneSkipLast);
NSParameterAssert(context1);
CGContextConcatCTM(context1, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context1, CGRectMake(0, 0, screenWidth,
screenWidth), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context1);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
儘可能使用內存。這就是爲什麼你被警告和/或系統崩潰。這不是你的代碼的問題,而是系統的問題。虛擬內存有時可能會有所幫助,並可能導致系統更加不穩定(更常出現故障)。 – 2014-10-03 04:58:02