如何计算AVAssetWriter进程的进度?所以,如果我有类似的东西:
[assetWriterInput requestMediaDataWhenReadyOnQueue:queue usingBlock:^{
while (1){
if ([assetWriterInput isReadyForMoreMediaData]) {
CMSampleBufferRef sampleBuffer = [audioMixOutput copyNextSampleBuffer];
if (sampleBuffer) {
[assetWriterInput appendSampleBuffer:sampleBuffer];
CFRelease(sampleBuffer);
} else {
[assetWriterInput markAsFinished];
break;
}
}
}
}];
Run Code Online (Sandbox Code Playgroud)
我可以在循环中拉动(或轮询)以确定我完成了多少x?
谢谢.
我确定我的缓冲区属性出了问题,但是我不清楚它是什么 - 它没有很好地记录应该去那里的东西,所以我猜是基于CVPixelBufferPoolCreate- 而Core Foundation对我来说几乎是一本封闭的书.
// "width" and "height" are const ints
CFNumberRef cfWidth = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &width);
CFNumberRef cfHeight = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &height);
CFStringRef keys[] = {
kCVPixelBufferWidthKey,
kCVPixelBufferHeightKey,
kCVPixelBufferCGImageCompatibilityKey
};
CFTypeRef values[] = {
cfWidth,
cfHeight,
kCFBooleanTrue
};
int numValues = sizeof(keys) / sizeof(keys[0]);
CFDictionaryRef bufferAttributes = CFDictionaryCreate(kCFAllocatorDefault,
(const void **)&keys,
(const void **)&values,
numValues,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks
);
AVAssetWriterInputPixelBufferAdaptor *adaptor = [[AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:(NSDictionary*)bufferAttributes] retain];
CVPixelBufferPoolRef bufferPool = adaptor.pixelBufferPool;
NSParameterAssert(bufferPool != NULL); // fails
Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个UIView,允许用户点击i中的按钮并录制屏幕(不是从相机制作视频),然后将其保存到文档文件夹中.我在这里看到了几篇SO文章,讨论了AVAssetWriter并引用了这个链接:http://codethink.no-ip.org/wordpress/archives/673 ,但该链接似乎已经死了.
但是,没有人真正展示过解决方案或提供了如何实现的任何示例.任何人有任何想法或能指出我正确的方向?这应该比它简单.
谢谢,道格
我有两种方法(一种用于音频,一种用于视频),它们通过各自的AVAssetWriterInput将它们各自的样本附加到AVAssetWriter.一切都适用于简单的启动和停止案例.这里的一些背景是音频流来自coreAudio,我已应用回声抑制,而视频输入来自AVCaptureVideoDataOutputSampleBufferDelegate,通过setSampleBufferDelegate从AVCaptureVideoDataOutput提供.
问题是当我想暂停录制,然后重新开始重新编码时,会对源的音频和视频部分发生不同的事情.到目前为止,我一直无法在暂停恢复后保持音频和视频同步.
看来,当通过appendSampleBuffera附加音频样本数据时,即使CMSampleBufferRef具有准确的时间戳,它似乎也没有"跳过"没有样本的时间段.我的意思是,当附加音频样本时,它并不关心CMSampleBuffer上的时间戳是什么......它只是不断地将样本背靠背堆积,即使有(例如)120秒音频数据中的差距,它不会为它创造一个"空白空间".
我坦率地不在乎,只要视频样本的行为是相同的(但事实并非如此).对于视频样本,得到的视频编码确实跳过了样本,尽管它在没有数据的时间段内产生了延长的空视频帧.
因此,从一个简单的实现,在暂停期间,您会在暂停期间获得一个空白视频部分,但对于音频部分,您将获得下一个未暂停部分的样本背靠背.这意味着暂停和取消暂停(通过抑制向avasset写入器添加缓冲区数据)会导致音频和视频之间完全失步.
我试过的补救措施:
使用CMSetAttachment()设置kCMSampleBufferAttachmentKey_FillDiscontinuitiesWithSilence - 对于音频通道,希望它能像视频流那样做.这根本没有效果.我可能做错了,但没有关于此的真实文档,所以在这个黑暗中拍摄.
在"暂停"的受影响持续时间内添加我自己的空样本(通过appendLapsedAudiotime).问题是我不认为我的缓冲区是正确的,而且我不清楚是否可以添加一个只有0或1个样本的音频缓冲区,并在很长一段时间内将其拉长.如果我也可以将音频缓冲区格式更改为在整个暂停期间执行1个样本,但是下游低级API将不太喜欢不稳定的采样率设置.
使用CMSampleBufferCreateCopyWithNewTiming()更改视频的呈现时间,以符合音频的行为.这证明既不稳定,也没有用.我对此进行了多次迭代,包括调整音频和视频的时间戳.这可能是我在那里犯了错误,但考虑到没有文件,我对这种方法也是盲目的.
使用多个startSessionAtSourceTime/endSessionAtSourceTime以及在暂停状态期间抑制写入示例,但这不起作用,实际上Apples头文件中的注释警告您不支持此操作(与其在线文档相反):注意:目前不支持多个样本编写会话.调用startSessionAtSourceTime是一个错误:在调用endSessionAtSourceTime后第二次:
所以我的下一个方法是创建多个AVAssets.当有一个"暂停开始"时,我将完成录音,当有"暂停"时,我将开始一个全新的录音,当完成所有操作后,我将使用AVAssetComposition来将它们全部重新组合在一起.我对这种方法感到有些紧张,因为我发现在设置新的av捕获时,快速av捕获停止并开始在各个地方出现无法解释的故障.在尝试开始新的av捕获之前,我可能不得不强制"取消暂停"等待一段时间.
所以问题是......有更好的方式吗?
我正在使用avassetwriter从音频图像阵列创建一个.mov,我想在创建视频中添加淡入/淡出效果,有人使用过任何代码吗?在此先感谢您的帮助!
...
for(UIImage * img in imageArray)
{
//UIImage * img = frm._imageFrame;
buffer = [self pixelBufferFromCGImage:[img CGImage]];
BOOL append_ok = NO;
int j = 0;
while (!append_ok && j < 30) {
if (adaptor.assetWriterInput.readyForMoreMediaData) {
//print out status:
NSLog(@"Processing video frame (%d,%d)",frameCount,[imageArray count]);
CMTime frameTime = CMTimeMake(frameCount*frameDuration,(int32_t) fps);
append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
if(!append_ok){
NSError *error = videoWriter.error;
if(error!=nil) {
NSLog(@"Unresolved error %@,%@.", error, [error userInfo]);
}
}
}
else {
printf("adaptor not ready %d, %d\n", frameCount, j);
[NSThread …Run Code Online (Sandbox Code Playgroud) 我想写一个连续捕获视频的iphone应用程序,h.264以10秒的间隔对它们进行编码并上传到存储服务器.这可以用avassetwriter完成,我可以继续删除旧文件,因为我创建了新文件.但是,由于闪存具有有限的写周期,因此该方案将在通过闪存几千次写入周期后破坏闪存.有没有办法将avassetwriter重定向到内存,或在iPhone上创建一个ram驱动器?
谢谢!
我iOS的文档中发现了AVAssetWriterInput可以传递nil的outputSettings字典来指定输入数据不应该被重新编码.
用于编码附加到输出的媒体的设置.传递nil以指定不应重新编码附加的样本.
我想利用这个功能传递原始H.264 NAL流,但是我无法将原始字节流调整为CMSampleBuffer可以传递到AVAssetWriterInput的appendSampleBuffer方法.我的NAL流只包含SPS/PPS/IDR/P NAL(1,5,7,8).我无法找到有关如何使用AVAssetWriter预编码H264数据的文档或结论性答案.生成的视频文件无法播放.
如何正确打包NAL单元CMSampleBuffers?我需要使用开始代码前缀吗?长度前缀?我需要确保每个只放一个NAL CMSampleBuffer吗?我的最终目标是使用H264/AAC创建MP4或MOV容器.
这是我一直在玩的代码:
-(void)addH264NAL:(NSData *)nal
{
dispatch_async(recordingQueue, ^{
//Adapting the raw NAL into a CMSampleBuffer
CMSampleBufferRef sampleBuffer = NULL;
CMBlockBufferRef blockBuffer = NULL;
CMFormatDescriptionRef formatDescription = NULL;
CMItemCount numberOfSampleTimeEntries = 1;
CMItemCount numberOfSamples = 1;
CMVideoFormatDescriptionCreate(kCFAllocatorDefault, kCMVideoCodecType_H264, 480, 360, nil, &formatDescription);
OSStatus result = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, NULL, [nal length], kCFAllocatorDefault, NULL, 0, [nal length], kCMBlockBufferAssureMemoryNowFlag, &blockBuffer);
if(result != noErr)
{
NSLog(@"Error creating CMBlockBuffer"); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用AVCaptureSession从摄像头捕获视频,然后我想使用AVAssetWriter将结果写入文件(具体来说,使用多个AVAssetWriters将捕获写入块视频,但我们不需要复杂化这个问题).但是,我无法确定实际需要将数据传递到AVAssetWriter的位置.在Apple Developer文档中,我只看到AVCaptureSession数据被传递给AVCaptureFileOutput.也许我只是错过了一些东西.AVAssetWriter可以用作捕获会话的输出吗?可以理解相关的示例或代码位(虽然不是必需的).非常感谢!
我在iOS应用程序上工作,我正在从图像创建视频.我AVAssetWriter用来实现这一目标.一切正常.但当应用程序进入后台并切换回来时,视频写入失败.AVAssetWriter的finishWritingWithCompletionHandler当我切换回应用程序是没有得到调用.
当应用程序在渲染期间进入背景时,可能是AVAssetWriter的副本失败,但我没有得到任何帮助.
对此有何看法?
谢谢
我正在使用PBJVision来实现点击录制视频功能.图书馆不支持方向,所以我正在尝试设计它.从我看到的,旋转视频有三种方法 - 我需要帮助决定最佳前进方式以及如何实现它.请注意,可以在点击到记录段之间进行轮换.因此,在录制会话中,方向被锁定为用户点击按钮时的方向.下次用户点击按钮进行录制时,应将方向重新设置为设备的方向(因此生成的视频显示为正面朝上).
方法1
旋转AVCaptureConnection使用setVideoOrientation:- 这会导致视频预览在每次切换时闪烁,因为这会切换实际的硬件.不酷,不可接受.
方法2transform在AVAssetWriterInput用于编写视频的对象上
设置属性.问题是,一旦资产编写者开始编写,该transform属性就无法更改,因此这仅适用于视频的第一部分.
方法3使用以下内容
旋转附加的图像缓冲区:如何直接在IOS 4中旋转CVImageBuffer图像而不转换为UIImage?但它一直在崩溃,我甚至不确定我是不是正在吠叫正确的树.有一个异常被抛出,我无法真正追溯到比我vImageRotate90_ARGB8888错误地使用该函数的事实.
关于我上面链接的GitHub问题页面的解释稍微详细一些.任何建议都会受到欢迎 - 说实话,我在AVFoundation上并不是很有经验,所以我希望有一些神奇的方法可以做到这一点,我甚至不知道!
avassetwriter ×10
ios ×6
objective-c ×6
iphone ×4
avfoundation ×3
h.264 ×2
video ×2
cocoa ×1
core-video ×1
xcode ×1