我正在尝试使用AVAssetWriter从图像生成视频,并为每个图像添加Ken Burns效果,这是我从图像数组创建视频的代码。
问题是如何为每个图像实施Ken Burns效果5秒
- (void) writeImagesAsMovie:(NSArray *)array toPath:(NSString*)path
{
UIImage *first = array[0];
CGSize frameSize = first.size;
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie
error:&error];
if(error) {
NSLog(@"error creating AssetWriter: %@",[error description]);
}
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:frameSize.width], AVVideoWidthKey,
[NSNumber numberWithInt:frameSize.height], AVVideoHeightKey,
nil];
AVAssetWriterInput* writerInput = [AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
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:
BOOL start = [videoWriter startWriting];
NSLog(@"Session started? %d", start);
[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);
[NSThread sleepForTimeInterval:0.05];
int fps = 1;
int i = 0;
for (UIImage *imgFrame in array)
{
if (adaptor.assetWriterInput.readyForMoreMediaData)
{
i++;
NSLog(@"inside for loop %d ",i);
CMTime frameTime = CMTimeMake(5, fps);
CMTime lastTime=CMTimeMake(i, fps);
CMTime presentTime=CMTimeAdd(lastTime, frameTime);
buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]];
BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
if (result == NO)
{
NSLog(@"failed to append buffer");
NSLog(@"The error is %@", [videoWriter error]);
}
if(buffer)
CVBufferRelease(buffer);
[NSThread sleepForTimeInterval:0.05];
}
else
{
NSLog(@"error");
i--;
}
[NSThread sleepForTimeInterval:0.02];
}
//Finish the session:
[writerInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^{
}];
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
LRProjectListViewController * proj = (LRProjectListViewController*)[[(UINavigationController*)DELEGATE.window.rootViewController viewControllers] firstObject];
[proj playVideoWithUrl:path];
}
答案 0 :(得分:0)
这取决于你在作文中写出的帧率。假设它是30FPS,那么在你的for循环中,每秒视频你需要30个帧。
for (UIImage *imgFrame in array)
您可以修改代码,以便为每个帧多次写入appendPixelBuffer作为替代方案。如果你想让它玩5秒钟,那么你需要循环(FPS * 5)次。但是在没有操纵框架的情况下,这只会给你一张5秒的静态图片。
在不知道您想要实现的细节的情况下,我认为这不是解决此问题的最佳方式。
相反,请查看将AVAnimations与AVVideoCompositionCoreAnimationTool一起使用。这将直接与AVAssetExportSession一起使用,这比使用AVAssetWriter更容易,除非您有非常具体的要求(通常需要操纵实际的视频帧)。