- 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/
我理解CMTime的概念以及它的作用。简而言之,我们有非常小的秒数表示为浮点数。添加后,它们会累积一个错误,随着解码/播放的进行,该错误变得很重要。例如求和一百万次0.000001给我们 1.0000
我想使用类 AVPlayer 的 Seek 方法。但是这个方法需要一个参数 CMTime。任何人都知道这个对象。 为了将播放光标移动到给定的时间。 最佳答案 Apple 文档包含有关 CMTime s
我正在编写一个使用 AVFoundation 和 CMTime 的应用程序。我已经记录了使用 CMTimeMake() 创建的 CMTime 实例的值。该值似乎四舍五入为最接近的整数。我需要一个具有精
我看过一些examples of CMTime (三个单独的链接),但我还是不明白。我将 AVCaptureSession 与 AVCaptureVideoDataOutput 一起使用,我想设置输出
我一直在查看与创建 CMTime 相关的文档。所有函数(CMTimeMake()、CMTimeMakeWithSeconds() 等)都采用名为 preferredTimeSale 的第二个参数。 有
我之前使用过 Core Data 的可转换属性,但没有使用过 C 对象,例如 CMTime。 我需要使用可转换在核心数据上存储 CMTime。 在模型对象上,我已将其声明为可转换的。 @propert
func addPeriodicTimeObserver(forInterval interval: CMTime, queue: DispatchQueue?, using block: @esca
CMTimeMake 没有给我预期的结果。以下代码: CMTime testTime = CMTimeMake(0, 30); NSLog(@"testTime w/ input 0, 30: val
我希望 CMTime 为人类可读的字符串。 所以我找到了下面的代码。 extension CMTime { var durationText:String { let tota
我正在创建一个应用程序,我必须在其中混合歌曲。我已经完成了这个,但问题是当我使用以下函数时。 - (BOOL)insertTimeRange:(CMTimeRange)timeRange ofTrac
我有一个小整数值,我想将它转换成 CMTime。 问题是 CMTime(value: _ , timeScale: _) 或 CMTimeMakeWithSeconds(value: _ , time
如何将当前播放时间增加 5 秒? 实际上这是我的代码: CMTime currentTime = music.currentTime; 我不能使用 CMTimeGetSeconds() ,因为我需要
这可能看起来很荒谬,但是如何在 Objective-C 中将 CMTime 的秒数输出到控制台?我只需要将该值除以时间刻度,然后以某种方式在控制台中看到它。 最佳答案 NSLog(@"seconds
我很难理解如何使用 AVAssetWriter 将 30fps 的运动 JPEG 流转换为视频文件。我没有得到的部分是[适配器 appendPixelBuffer:buffer withPresent
我有一个 AVPlayer,我想在 11.593 秒的特定时间开始播放。我从 URL 字符串中检索到这个数字(以毫秒为单位),将其转换为 Double,然后转换为 CMTime,如下所示: http:
我有一个 iPhone 摄像头附件,可以以 9FPS 的速度捕捉视频,并将其作为单独的 UIImages 提供。我正在尝试将这些图像拼接在一起,以使用 AVFoundation 创建相机所见内容的延时
1) CMTimeMake(1,10) 表示持续时间为 1 秒,时间刻度为 10,即每秒 10 帧。这意味着 10 帧的视频持续时间为 1 秒? 2) CMTime lastTime=CMTimeMa
我有以下 2 行代码正在迁移到 Swift,但我有点卡住了。 CMTime trimmingTime = CMTimeMake(lround(videoAsset.naturalTimeScale /
我有一个 AVQueuePlayer,我正在尝试在按下按钮时向后搜索 5 秒。 我的代码如下: func seekBack() { guard let currentTime = self.p
我正在尝试使用 AVFoundation 播放视频。我将以下代码用于将播放推进一帧的按钮。 它间歇性地工作,在某些执行中它会做正确的事情并前进一帧,但大多数时候我必须按下按钮 3 或 4 次才能前进一
我是一名优秀的程序员,十分优秀!