- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我正在使用 AVAssetWriterInputPixelBufferAdaptor
将一些帧写入视频,并且行为 w.r.t.时间不是我所期望的。
如果我只写一帧:
[videoWriter startSessionAtSourceTime:kCMTimeZero];
[adaptor appendPixelBuffer:pxBuffer withPresentationTime:kCMTimeZero];
这让我得到了一个长度为零的视频,这正是我所期望的。
但如果我继续添加第二帧:
// 3000/600 = 5 sec, right?
CMTime nextFrame = CMTimeMake(3000, 600);
[adaptor appendPixelBuffer:pxBuffer withPresentationTime:nextFrame];
我得到了 10 秒的视频,而我期望是 5 秒。
这是怎么回事? withPresentationTime
是否以某种方式设置帧的开始和持续时间?
请注意,我没有调用 endSessionAtSourceTime
,只是调用 finishWriting
。
最佳答案
尝试查看此示例并进行逆向工程以在 5 秒后添加 1 帧...
这里是示例代码链接:git@github.com:RudyAramayo/AVAssetWriterInputPixelBufferAdaptorSample.git
这是您需要的代码:
- (void) testCompressionSession
{
CGSize size = CGSizeMake(480, 320);
NSString *betaCompressionDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
NSError *error = nil;
unlink([betaCompressionDirectory UTF8String]);
//----initialize compression engine
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:betaCompressionDirectory]
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(@"I can add this input");
else
NSLog(@"i can't add this input");
[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
//---
// insert demo debugging code to write the same image repeated as a movie
CGImageRef theImage = [[UIImage imageNamed:@"Lotus.png"] CGImage];
dispatch_queue_t dispatchQueue = dispatch_queue_create("mediaInputQueue", NULL);
int __block frame = 0;
[writerInput requestMediaDataWhenReadyOnQueue:dispatchQueue usingBlock:^{
while ([writerInput isReadyForMoreMediaData])
{
if(++frame >= 120)
{
[writerInput markAsFinished];
[videoWriter finishWriting];
[videoWriter release];
break;
}
CVPixelBufferRef buffer = (CVPixelBufferRef)[self pixelBufferFromCGImage:theImage size:size];
if (buffer)
{
if(![adaptor appendPixelBuffer:buffer withPresentationTime:CMTimeMake(frame, 20)])
NSLog(@"FAIL");
else
NSLog(@"Success:%d", frame);
CFRelease(buffer);
}
}
}];
NSLog(@"outside for loop");
}
- (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);
// CVReturn status = CVPixelBufferPoolCreatePixelBuffer(NULL, adaptor.pixelBufferPool, &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, kCGImageAlphaPremultipliedFirst);
NSParameterAssert(context);
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
关于objective-c - AVAssetWriterInputPixelBufferAdaptor 和 CMTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5808557/
我使用下面的代码将图像写入视频 -(void) writeImagesToMovieAtPath:(NSString *) path withSize:(CGSize) size { NSLo
我确定我的缓冲区属性有问题,但我不清楚是什么 -- 没有很好地记录应该去那里的内容,所以我猜测基于 CVPixelBufferPoolCreate -- Core Foundation 对我来说几乎是
我正在尝试制作一个应用程序来记录 UIImageView 的内容以及麦克风音频,并将它们实时记录到视频中。 (有点像会说话的汤姆猫应用程序) 我正在使用 AVAssetWriterInputPixel
我正在捕捉相机画面并将其写入电影。我遇到的问题是,在导出电影之后,它前面有几秒钟的黑色(相对于实际录制开始时间)。 我认为这与[self.assetWriter startSessionAtSourc
我将 CVPixelBufferRefs 附加到连接到 AVAssetWriterInput 的 AVAssetWriterInputPixelBufferAdaptor 以使用 AVAssetWri
我正在尝试以预期的帧速率将 CVPixelBuffers 附加到 AVAssetWriterInputPixelBufferAdaptor,但它似乎太快了,而且我的数学失败了。这不是从相机捕捉,而是捕
我正在使用 AVAssetWriterInputPixelBufferAdaptor 将一些帧写入视频,并且行为 w.r.t.时间不是我所期望的。 如果我只写一帧: [videoWriter sta
我正在尝试使用为 encoding asset writer 提供的示例的组合。以及 pixelBufferFromCGImage 提供的样本在我正在导出的 AVAsset 上覆盖 UIImage。
我在 AVAssetWriterInputPixelBufferAdaptor 中使用 pixelBufferPool 来创建像素缓冲区以与 append 方法一起使用。创建4个buffer后,pix
我正在从一组图像创建一个视频文件。我能够在模拟器上创建视频文件,但是当我尝试在设备上运行相同的代码时,它会出现以下错误: NSURLErrorDomain Code=-3000 "Cannot cre
我已经使用以下代码成功地从图像创建了视频 -(void)writeImageAsMovie:(NSArray *)array toPath:(NSString*)path size:(CGSize)s
我正在尝试使用 ReplayKit 记录我的应用程序的屏幕,在录制视频时裁剪掉其中的某些部分。不太顺利。 ReplayKit 将捕获整个屏幕,因此我决定从 ReplayKit 接收每一帧(作为 CMS
我是一名优秀的程序员,十分优秀!