我有以下测试代码,它应该在OSX中创建一个图像文件的视频文件。但是,如果运行成功,视频文件无法播放....
有人能想到我可能做错了什么或错过了吗?
- (void)testVideoWriter {
NSImage *someImage = [NSImage imageNamed:@"002"];
CGSize size = CGSizeMake(someImage.size.width, someImage.size.height);
CMTime frameLength = CMTimeMake(1, 5);
CMTime currentTime = kCMTimeZero;
NSError *error = nil;
//remember to delete video before re-runnign or you will get fails...
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:@"/Users/petertribe/Desktop/testvideo.mov"] fileType:AVFileTypeMPEG4 error:&error];
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:k32ARGBPixelFormat],
kCVPixelBufferPixelFormatTypeKey, nil];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];
[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
for (int i = 0; i < 100; i++)
{
CVPixelBufferRef pixel_buffer = [self fastImageFromNSImage:someImage];
while (adaptor.assetWriterInput.readyForMoreMediaData == FALSE) {
NSDate *maxDate = [NSDate dateWithTimeIntervalSinceNow:0.1];
[[NSRunLoop currentRunLoop] runUntilDate:maxDate];
}
if(![adaptor appendPixelBuffer:pixel_buffer withPresentationTime:currentTime]) {
NSLog(@"FAIL");
} else {
NSLog(@"Success:%d", i);
currentTime = CMTimeAdd(currentTime, frameLength);
}
CVPixelBufferRelease(pixel_buffer);
}
[writerInput markAsFinished];
NSLog(@"Done");
}
- (CVPixelBufferRef)fastImageFromNSImage:(NSImage *)image
{
CVPixelBufferRef buffer = NULL;
// config
size_t width = [image size].width;
size_t height = [image size].height;
size_t bitsPerComponent = 8;
CGColorSpaceRef cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGBitmapInfo bi = kCGImageAlphaNoneSkipFirst;
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
// create pixel buffer
CVPixelBufferCreate(kCFAllocatorDefault, width, height, k32ARGBPixelFormat, (__bridge CFDictionaryRef)d, &buffer);
CVPixelBufferLockBaseAddress(buffer, 0);
void *rasterData = CVPixelBufferGetBaseAddress(buffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(buffer);
// context to draw in, set to pixel buffer's address
CGContextRef ctxt = CGBitmapContextCreate(rasterData, width, height, bitsPerComponent, bytesPerRow, cs, bi);
if(ctxt == NULL){
NSLog(@"could not create context");
return NULL;
}
// draw
NSGraphicsContext *nsctxt = [NSGraphicsContext graphicsContextWithGraphicsPort:ctxt flipped:NO];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:nsctxt];
[image drawAtPoint:NSMakePoint(0, 0) fromRect:NSMakeRect(0, 0, image.size.width, image.size.height) operation:NSCompositeCopy fraction:1];
[NSGraphicsContext restoreGraphicsState];
CVPixelBufferUnlockBaseAddress(buffer, 0);
CFRelease(ctxt);
return buffer;
}
答案 0 :(得分:1)
好的,我必须有一些有趣的时刻,修复很简单......
只需添加
[videoWriter finishWriting];
到testVideoWriter方法的末尾,解决了问题