我有几个UIImages,我想从他们那里创建一个视频。
我使用了解决方案based on this
从UIImages创建视频。就我而言,我想创建一个30 fps的视频。所以,每张图片都是1/30秒。
设置好所有内容以开始保存视频后,如该页面所述,我创建了一个方法,将一个图像保存到电影中,并通过循环调用此方法。类似的东西:
for (int i=0; i<[self.arrayOfFrames count]; i++ {
UIImage *oneImage = [self.arrayOfFrames objectAtIndex:i];
[self saveOneFrame:oneImage atTime:i];
}
,方法是
-(void)saveOneFrame:(UIImage *)imagem atTime:(NSInteger)time {
// I have tried this autorelease pool to drain memory after the method is finished
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CVPixelBufferRef buffer = NULL;
buffer = [self pixelBufferFromCGImage:imagem.CGImage size:imagem.size];
BOOL append_ok = NO;
int j = 0;
while (!append_ok && j < 30)
{
if (adaptor.assetWriterInput.readyForMoreMediaData)
{
printf("appending %d attemp %d\n", time, j);
CMTime oneFrameLength = CMTimeMake(1, 30.0f ); // one frame = 1/30 s
CMTime lastTime;
CMTime presentTime;
if (time == 0) {
presentTime = CMTimeMake(0, self.FPS);
} else {
lastTime = CMTimeMake(tempo-1, self.FPS);
presentTime = CMTimeAdd(lastTime, duracaoUmFrame);
}
// this will always add 1/30 to every new keyframe
CMTime presentTime = CMTimeAdd(lastTime, oneFrameLength);
append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
CVPixelBufferPoolRef bufferPool = adaptor.pixelBufferPool;
NSParameterAssert(bufferPool != NULL);
[NSThread sleepForTimeInterval:0.05];
}
else
{
printf("adaptor not ready %d, %d\n", time, j);
[NSThread sleepForTimeInterval:0.1];
}
j++;
}
if (!append_ok) {
printf("error appending image %d times %d\n", time, j);
}
CVBufferRelease(buffer);
[pool drain]; // I have tried with and without this autorelease pool in place... no difference
}
在将50帧保存到电影后,应用程序只是退出而没有任何警告......
这是另一种方法:
-(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;
}
我运行乐器并且在电影开始保存之前没有检测到任何泄漏或夸大的内存使用情况。
任何线索?
注:
查看设备日志后,我发现了这个:
<Notice>: (UIKitApplication:com.myID.myApp[0xc304]) Bug: launchd_core_logic.c:3732 (25562):3
<Notice>: (UIKitApplication:com.myID.myApp[0xc304]) Assuming job exited: <rdar://problem/5020256>: 10: No child processes
<Warning>: (UIKitApplication:com.myID.myApp[0xc304]) Job appears to have crashed: Segmentation fault: 11
<Warning>: Application 'myApp' exited abnormally with signal 11: Segmentation fault: 11
答案 0 :(得分:0)
也许你已经尝试过了,但this可以提供帮助吗?
最后,解决方案是重启iPhone,因为有些数据 腐败了。重启后一切正常。
应该想到经典“你试过关掉它吗? 又一次?“
答案 1 :(得分:0)
以这种方式看待它,你有一个图像数组(这会占用大量内存)。您正在复制这些图像中的每一个并将副本保存到已完成的电影中。因此,您的要求基本上是您开始时的两倍。如果在添加框架后释放每个框架怎么样?这意味着你可能会以相同的大小(或者可能更大,但仍然小于你的内存使用量)结束。