我正在使用AVCaptureSession从设备麦克风和摄像头捕获音频和视频样本.
然后我尝试编写通过AVCaptureSessions委托方法返回的CMSampleBuffers(使用AVAssetWriter和AVAssetWriterInputs)
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer: (CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
Run Code Online (Sandbox Code Playgroud)
当我的音频AVAssetWriterInput配置为以Apple Lossless格式(kAudioFormatAppleLossless)写出数据时,这可以正常工作但是如果我尝试配置音频AVAssetWriterInput以使用AAC(kAudioFormatMPEG4AAC)它成功写入视频和音频样本大约500ms然后失败跟随错误
writer has failed with Error Domain=AVFoundationErrorDomain Code=-11821 "Cannot Decode" UserInfo=0x4b2630 {NSLocalizedFailureReason=The media data could not be decoded. It may be damaged., NSUnderlyingError=0x4ad0f0 "The operation couldn’t be completed. (OSStatus error 560226676.)", NSLocalizedDescription=Cannot Decode}
Run Code Online (Sandbox Code Playgroud)
这是我用来创建AVAssetWriter和AVAssetWriterInputs的代码
NSError *error = nil;
m_VideoCaputurePath = [[NSString stringWithFormat:@"%@/%@.mp4",[UserData getSavePath],[UserData getUniqueFilename]] retain];
if( USE_AAC_AUDIO )
{
m_audioAndVideoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:m_VideoCaputurePath] fileType:AVFileTypeMPEG4 error:&error];
}
else
{
m_audioAndVideoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:m_VideoCaputurePath] fileType:AVFileTypeQuickTimeMovie error:&error];
}
//\Configure …Run Code Online (Sandbox Code Playgroud) 我AVAssetWriter用来压缩视频,代码适用于iOS7中的iPhone 5和4.我试图使用AVVideoProfileLevelKeyof AVVideoProfileLevelH264High41来获得比Baseline或Main配置文件更好的压缩效果.该代码在iOS7中使用iPhone 5,但在iPhone 4上出现以下错误.下面的错误中列出的大多数这些配置文件另外不起作用.
有谁知道如果用于压缩的High配置文件在iPhone 4上不起作用,Apples文档仅表明它需要iOS6或更高版本.
> 2013-12-10 18:26:37.637 VideoCompression[677:3707] *** Terminating app
> due to uncaught exception 'NSInvalidArgumentException', reason: '***
> `-[AVAssetWriterInput initWithMediaType:outputSettings:sourceFormatHint:]` For compression
> property ProfileLevel, video codec type avc1 only allows the following
> values: H264_Baseline_1_3, H264_Baseline_3_0, H264_Baseline_3_1,
> H264_Baseline_4_1, H264_Main_3_0, H264_Main_3_1, H264_Main_3_2,
> H264_Main_4_0, H264_Main_4_1, H264_Main_5_0, H264_High_5_0,
> H264_Baseline_AutoLevel, H264_Main_AutoLevel, H264_High_AutoLevel'
> *** First throw call stack: (0x2fd76f4b 0x3a1066af 0x2ec5d833 0x2ec5d70b 0x2ec5d67d
0xbd001 0xbba59 0x3a5e9d1b 0x3a5ea293 0x3a5ea6f7
> 0x3a5fc8f9 …Run Code Online (Sandbox Code Playgroud) 我知道如何使用AVAssetReader和AVAssetWriter,并成功地使用它们从一部电影中获取视频轨道并将其转码为另一部电影.但是,我也想用音频来做这件事.在完成初始转码后,我是否必须创建和AVAssetExportSession,或者在写入会话期间是否有某种方式在轨道之间切换?我不想处理AVAssetExportSession的开销.
我问,因为,使用拉式方法 - (while([assetWriterInput isReadyForMoreMediaData]){...} - 仅假设一个轨道.它如何用于多个轨道,即音频和视频轨道?
我有一个iPhone视频录制应用程序.我AVAssetWriter用于将录制的视频数据写入文件.我也有兴趣将自定义元数据嵌入到文件中.例如:我想将我的应用程序识别为视频的创建者.
因此,在创建资产编写者之后,我使用密钥将创建者值添加AVMetadataCommonKeyCreator到资产编写者的元数据中.
代码段如下:
AVAssetWriter *assetWrtr = [[AVAssetWriter alloc] initWithURL:inURL fileType:AVFileTypeQuickTimeMovie error:&error];
self.assetWriter = assetWrtr;
[assetWrtr release];
NSArray *existingMetadataArray = self.assetWriter.metadata;
NSMutableArray *newMetadataArray = nil;
if (existingMetadataArray)
{
newMetadataArray = [existingMetadataArray mutableCopy]; // To prevent overriding of existing metadata
}
else
{
newMetadataArray = [[NSMutableArray alloc] init];
}
AVMutableMetadataItem *item = [[AVMutableMetadataItem alloc] init];
item.keySpace = AVMetadataKeySpaceCommon;
item.key = AVMetadataCommonKeyCreator;
item.value = @"My App";
[newMetadataArray addObject:item];
self.assetWriter.metadata = newMetadataArray;
[newMetadataArray release];
[item release];
Run Code Online (Sandbox Code Playgroud)
录制完成后,我尝试使用AVURLAsset读取文件的内容.
NSURL *outputFileURL = …Run Code Online (Sandbox Code Playgroud) 我在AVAssetWriterInputPixelBufferAdaptor中使用pixelBufferPool来创建像素缓冲区以与append方法一起使用.创建4个缓冲区后,pixelBufferPool属性变为NULL;
我设置了我的编写器,输入和适配器,如下所示:
- (BOOL) setupRecorder {
NSError *error = nil;
if([[NSFileManager defaultManager] fileExistsAtPath:[[self tempFileURL] path]])
[[NSFileManager defaultManager] removeItemAtURL:[self tempFileURL] error:&error];
assetWriter = [[AVAssetWriter alloc] initWithURL: [self tempFileURL]
fileType:AVFileTypeQuickTimeMovie
error:&error];
if (error) {
NSLog(@"Error creating asset writer: %@", error);
[assetWriter release];
return NO;
}
// writer
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:videoWidth], AVVideoWidthKey,
[NSNumber numberWithInt:videoHeight], AVVideoHeightKey,
nil];
assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey,
nil];
adaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:assetWriterInput sourcePixelBufferAttributes:bufferAttributes];
[adaptor …Run Code Online (Sandbox Code Playgroud) 尽管StackOverflow上有很好的信息,但我仍然在这里尽力而为......
我正在尝试将OpenGL渲染缓冲区写入iPad 2上的视频(使用iOS 4.3).这正是我正在尝试的:
A)设置AVAssetWriterInputPixelBufferAdaptor
创建一个指向视频文件的AVAssetWriter
使用适当的设置设置AVAssetWriterInput
设置AVAssetWriterInputPixelBufferAdaptor以将数据添加到视频文件中
B)使用该AVAssetWriterInputPixelBufferAdaptor将数据写入视频文件
将OpenGL代码渲染到屏幕上
通过glReadPixels获取OpenGL缓冲区
从OpenGL数据创建CVPixelBufferRef
使用appendPixelBuffer方法将PixelBuffer附加到AVAssetWriterInputPixelBufferAdaptor
但是,我遇到了这个问题.我现在的策略是在按下按钮时设置AVAssetWriterInputPixelBufferAdaptor.一旦AVAssetWriterInputPixelBufferAdaptor有效,我设置一个标志来通知EAGLView创建一个像素缓冲区,并通过appendPixelBuffer将它附加到视频文件中给定数量的帧.
现在我的代码崩溃,因为它试图附加第二个像素缓冲区,给我以下错误:
-[__NSCFDictionary appendPixelBuffer:withPresentationTime:]: unrecognized selector sent to instance 0x131db0
Run Code Online (Sandbox Code Playgroud)
这是我的AVAsset设置代码(很多是基于Rudy Aramayo的代码,它可以在普通图像上工作,但不是为纹理设置的):
- (void) testVideoWriter {
//initialize global info
MOVIE_NAME = @"Documents/Movie.mov";
CGSize size = CGSizeMake(480, 320);
frameLength = CMTimeMake(1, 5);
currentTime = kCMTimeZero;
currentFrame = 0;
NSString *MOVIE_PATH = [NSHomeDirectory() stringByAppendingPathComponent:MOVIE_NAME];
NSError *error = nil;
unlink([betaCompressionDirectory UTF8String]);
videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:betaCompressionDirectory] fileType:AVFileTypeQuickTimeMovie error:&error];
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:size.width], AVVideoWidthKey, …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用本地m4a或mp3文件并压缩/下采样此文件(用于制作较小的文件).
最初,我使用AVAssetExportSession将AVAsset导出到临时目录,但我没有对压缩/下采样的任何控制(你只能使用预设,其中只有.wav文件格式支持质量下降) .
然后,按照SO上的几个例子,我尝试使用AVAssetReader/AVAssetWriter来预先形成这个'export'.
我这样创建我的读者/作者:
NSString *exportPath = [NSHomeDirectory() stringByAppendingPathComponent:@"out.m4a"];
NSURL *exportURL = [NSURL fileURLWithPath:outPath];
// reader
NSError *readerError = nil;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset
error:&readerError];
AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVAssetReaderTrackOutput *readerOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track
outputSettings:nil];
[reader addOutput:readerOutput];
// writer
NSError *writerError = nil;
AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:exportURL
fileType:AVFileTypeAppleM4A
error:&writerError];
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
// use different values to affect the downsampling/compression
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: …Run Code Online (Sandbox Code Playgroud) 一个多星期以来,我一直在努力解决这个问题.我希望有人看到我做错了什么.我试图使用finishWritingWithCompletionHandler:方法,因为现在不推荐使用finishWriting方法.我没有使用新方法取得任何成功.它失败,出现未知错误-11800.我可以使用过时的方法精细救我的MOV文件,但是当我用新的方法来创建等同失败每次.
这是我的原始代码:
dispatch_async(movieWritingQueue, ^{
if ([self.assetWriter finishWriting]) {
self.assetWriterAudioIn = nil;
self.assetWriterVideoIn = nil;
//[assetWriter release]; ARC will not allow this line.
self.assetWriter = nil;
self.readyToRecordVideo = NO;
self.readyToRecordAudio = NO;
[self.delegate movieReadyToSaveForMovieProcessor:self];
}
else {
[self displayError:[assetWriter error]];
dispatch_async(dispatch_get_main_queue(), ^{
[self resumeCaptureSession];
});
}
}];
Run Code Online (Sandbox Code Playgroud)
我的新方法如下:
dispatch_async(movieWritingQueue, ^{
[self.assetWriter finishWritingWithCompletionHandler:^{
if (self.assetWriter.status != AVAssetWriterStatusFailed && self.assetWriter.status == AVAssetWriterStatusCompleted) {
self.assetWriterAudioIn = nil;
self.assetWriterVideoIn = nil;
self.assetWriter = nil;
self.readyToRecordAudio = NO;
self.readyToRecordVideo = NO;
[self.delegate movieReadyToSaveForMovieProcessor:self];
} else { …Run Code Online (Sandbox Code Playgroud) 我正在为我的某个应用构建视频导出功能.从本质上讲,视频是一系列六种不同图像中的一种,持续时间不同(短).
当我导出包含283个不同持续时间图像的东西时,导出工作正常,但是当我尝试导出803中的一个时,我得到了可怕的"操作无法完成"错误(AKA"我们不知道是什么爆炸因为AVFoundation错误报告很糟糕").
当我尝试使用my AVAssetWriterInputPixelBufferAdaptor,return appendPixelBuffer:withPresentationTime:返回第754帧(总是第754帧)时NO,AVAssetWriter状态失败,错误是这样的:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17ab2050 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-16364)}
Run Code Online (Sandbox Code Playgroud)
我不能为我的生活找出底层错误(OSStatus-16364)是什么.www.osstatus.com不知道,macerror说没有这样的东西,这个用于搜索SDK标题的Python脚本什么也没发现.它也不是像一些OSStatus错误那样的四字符代码(除非我搞砸了这个).
我已经排除了我发现的"操作无法完成"错误的每个常见原因.它与文件系统权限或覆盖无关,没有两个调用appendPixelBuffer具有相同的显示时间.
它不是内存(视频导出期间内存使用率保持在165MB),CPU保持在3%左右.
如果它具有任何重要性,我会对CVPixelBuffer6个图像反复重复使用相同的6 秒,而不是UIImage每次都从s 创建新的图像.这似乎有助于性能,并且每次都将其更改为新的并不会改变任何东西(除了让它在第753帧上失败),但谁知道.
有谁知道这可能是什么?
我使用这个广受欢迎的库来记录像Vine这样的视频片段:https://github.com/rFlex/SCRecorder
它运行良好,在演示中它为所有创建的视频添加了水印,但问题是它将标记添加到当前会话的所有段.我希望能够允许用户在各个段上添加类似于Snapchat的文本标题.我在搜索时遇到过这篇文章,但我对如何将其应用于单个片段感到很遗憾:如何在视频上添加叠加文本,然后对其进行重新编码?
我不是在找人给我一个完整的答案,只是找一个AVFoundation大师给我一个粗略的抽象概述将要涉及的步骤....我可以做研究并尝试弄清楚自己.
avassetwriter ×10
ios ×8
avfoundation ×5
iphone ×4
objective-c ×2
video ×2
audio ×1
ios6 ×1
metadata ×1
osstatus ×1
transcoding ×1
xcode ×1
xcode4 ×1