主要功能是将一个UIImage数组转为视频,并且存入相册。直接给出.m文件吧:
//
// PViewController.m
// test
//
// Created by pingshw on 14-3-30.
// Copyright (c) 2014年 pingshw. All rights reserved.
//
#import "PViewController.h"
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
#define kCGImageAlphaPremultipliedLast (kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast)
#else
#define kCGImageAlphaPremultipliedLast kCGImageAlphaPremultipliedLast
#endif
#define DOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/"]
#define VideoPath [DOCSFOLDER stringByAppendingPathComponent:@"test.mov"] //注意格式!
#define w 320
#define h 480
@interface PViewController ()
{
NSMutableArray *imageArr;
NSDictionary *options;
}
@end
@implementation PViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self startRecord:VideoPath];
}
-(CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image size:(CGSize)size
{
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, w, h, kCVPixelFormatType_32ARGB, (CFDictionaryRef) CFBridgingRetain(options), &pxbuffer);
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, kCGImageAlphaPremultipliedLast);
NSParameterAssert(context);
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
-(void)startRecord:(NSString *)moviePath
{
NSDate *start = [NSDate date];
if([[NSFileManager defaultManager] fileExistsAtPath:moviePath])
{
[[NSFileManager defaultManager] removeItemAtPath:moviePath error:nil];
}
imageArr = [[NSMutableArray alloc] init];
float total = 30.0;
int i = total;
while (i >0) {
i--;
UIGraphicsBeginImageContext(CGSizeMake(w, h));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, i/total, i/total, i/total, 1);
CGContextFillRect(context, CGRectMake(0, 0, w, h));
UIImage *image= UIGraphicsGetImageFromCurrentImageContext();
[imageArr addObject:image];
UIGraphicsEndImageContext();
NSLog(@"%d",i);
}//这里是生成了一个长度为total的测试数组,图片是纯色,颜色渐变,实际使用时替换为实际UIImage数组即可。
CGSize size = CGSizeMake(w, h);
NSError *error = nil;
unlink([moviePath UTF8String]);
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:moviePath]
fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(videoWriter);
if(error)
NSLog(@"error = %@", [error localizedDescription]);
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:size.width], AVVideoWidthKey,
[NSNumber numberWithInt:size.height], AVVideoHeightKey, nil];
AVAssetWriterInput *writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
if ([videoWriter canAddInput:writerInput])
NSLog(@"start");
[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
dispatch_queue_t dispatchQueue = dispatch_queue_create("record", NULL);
int __block frame = 0;
[writerInput requestMediaDataWhenReadyOnQueue:dispatchQueue usingBlock:^{
CVPixelBufferRef buffer = NULL;
while ([writerInput isReadyForMoreMediaData])
{
if([imageArr count] == 0)
{
[writerInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^{
UISaveVideoAtPathToSavedPhotosAlbum (moviePath,nil,nil, nil);
}];//存入相册,模拟器调试在模拟器文件夹能看到视频,真机调试在相册能找到存入的视频。
if (buffer)
{
CFRelease(buffer);
buffer = NULL;
}
break;
}
else
{
if (buffer==NULL)
{
buffer = [self pixelBufferFromCGImage:[[imageArr objectAtIndex:0] CGImage] size:size];
}
if (buffer)
{
CFAbsoluteTime interval = (total - [imageArr count]) * 50.0;//帧与帧的时间间隔
CMTime currentSampleTime = CMTimeMake((int)interval, 1000);
if([adaptor appendPixelBuffer:buffer withPresentationTime:currentSampleTime])
{
++frame;
[imageArr removeObjectAtIndex:0];
CFRelease(buffer);
buffer = NULL;
}
}
}
}
}];
NSDate *end = [NSDate date];
NSLog(@"%f",[end timeIntervalSinceDate:start]);//测试了下,真机,这个程序要跑0.55s
}
@end