我已经在这里和其他论坛中以不同的形式多次看到这个问题.有些问题得到了解答,有些则没有.回答者或作者声称有一些成功的地方.我已经实现了那些声称成功的例子,但还没有看到相同的结果.
当从AVCaptureSession获取样本缓冲区时,我能够成功地使用AVAssetWriter(和AVAssetWriterInputPixelBufferAdaptor)同时写入图像数据和音频数据.但是,如果我有以其他方式生成的CGImageRef,并且"从头开始"构建CVPixelBufferRef,则AVAssetWriterInputPixelBufferAdaptor的appendPixelBuffer:withPresentationTime方法会成功几帧,然后对所有后续帧都会失败.生成的影片文件当然无效.
您可以在http://pastebin.com/FCJZJmMi上看到我的示例代码
图像有效,并通过在调试窗口中显示来验证(参见第50-53行).该应用程序已经过仪器测试,在整个应用程序运行期间内存利用率很低.它没有得到任何内存警告.
据我所知,我已经遵循了可用的文档.为什么示例代码失败?需要做些什么来解决它?
如果有人成功获得AVAssetWriterInputPixelBufferAdaptor来处理他们自己的图像,请加入.
我正在尝试将音频用于iOS应用程序的视频.视频很好.文件中没有录制音频(我的iPhone扬声器工作.)
这是init设置:
session = [[AVCaptureSession alloc] init];
menu->session = session;
menu_open = NO;
session.sessionPreset = AVCaptureSessionPresetMedium;
camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
microphone = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
menu->camera = camera;
[session beginConfiguration];
[camera lockForConfiguration:nil];
if([camera isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]){
camera.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
}
if([camera isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]){
camera.focusMode = AVCaptureFocusModeContinuousAutoFocus;
}
if([camera isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]){
camera.whiteBalanceMode = AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance;
}
if ([camera hasTorch]) {
if([camera isTorchModeSupported:AVCaptureTorchModeOn]){
[camera setTorchMode:AVCaptureTorchModeOn];
}
}
[camera unlockForConfiguration];
[session commitConfiguration];
AVCaptureDeviceInput * camera_input = [AVCaptureDeviceInput deviceInputWithDevice:camera error:nil];
[session addInput:camera_input];
microphone_input = [[AVCaptureDeviceInput deviceInputWithDevice:microphone error:nil] retain];
AVCaptureVideoDataOutput * …Run Code Online (Sandbox Code Playgroud) 我正在编写一个自定义的Movie Recording应用程序,并已实现了AVAssetWriter和AVAssetWriterInputPixelBufferAdaptor,用于将帧写入文件.在DataOutputDelegate回调中,我尝试将CIFilter应用于sampleBuffer.首先,我得到一个CVPixelBufferRef,然后创建一个CIImage.然后我应用CIIFilter并获取生成的CIImage:
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage *image = [CIImage imageWithCVPixelBuffer:pixelBuffer];
CIFilter *hueAdjust = [CIFilter filterWithName:@"CIHueAdjust"];
[hueAdjust setDefaults];
[hueAdjust setValue: image forKey: @"inputImage"];
[hueAdjust setValue: [NSNumber numberWithFloat: 2.094]
forKey: @"inputAngle"];
CIImage *result = [hueAdjust valueForKey: @"outputImage"];
CVPixelBufferRef newBuffer = //Convert CIImage...
Run Code Online (Sandbox Code Playgroud)
我将如何转换CIImage以便我可以:
[self.filteredImageWriter appendPixelBuffer:newBuffer withPresentationTime:lastSampleTime];
Run Code Online (Sandbox Code Playgroud) 如何使用AVAssetWriterAPI更改视频(.mp4)元信息?
我不想重新编码。只想修改视频元信息。
下一段代码怎么写?
AVAssetWriter *writer = [AVAssetWriter assetWriterWithURL:[NSURL URLWithString:myPath] fileType:AVFileTypeQuickTimeMovie error:nil];
Run Code Online (Sandbox Code Playgroud)
如果我弄错了,请给我一些提示。
谢谢!!
我使用的API只给出了纹理对象的整数id,我需要将该纹理的数据传递给AVAssetWriter来创建视频.
我知道如何从像素缓冲区(CVPixelBufferRef)创建CVOpenGLESTexture对象,但在我的情况下,我必须以某种方式复制只有id可用的纹理数据.
换句话说,我需要将opengl纹理复制到基于pixelbuffer的纹理对象.可能吗?如果是,那怎么样?
在我的示例代码中,我有类似的东西:
void encodeFrame(Gluint textureOb)
{
CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferAdaptor pixelBufferPool], &pixelBuffer[0]);
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, coreVideoTextureCache, pixelBuffer[0],
NULL, // texture attributes
GL_TEXTURE_2D,
GL_RGBA, // opengl format
(int)FRAME_WIDTH,
(int)FRAME_HEIGHT,
GL_BGRA, // native iOS format
GL_UNSIGNED_BYTE,
0,
&renderTexture[0]);
CVPixelBufferLockBaseAddress(pixelBuffer[pixelBuffernum], 0);
//Creation of textureOb is not under my control.
//All I have is the id of texture.
//Here I need the data of textureOb somehow be appended as a video frame.
//Either by copying the data to pixelBuffer or somehow pass the textureOb …Run Code Online (Sandbox Code Playgroud) 我正在尝试裁剪视频帧。我已经使用AVFoundation框架录制了视频。我需要将捕捉的图像和录制的视频裁剪为正方形。我已经完成了UIImage工作,现在我正在尝试裁剪视频。
Run Code Online (Sandbox Code Playgroud)- (UIImage *)squareImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { // Cropping UIImage is working fine. CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0,0, image.size.width, image.size.width)); UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; CGImageRelease(imageRef); return result; }
我尝试裁剪视频,但结果是整个视频帧都没有裁剪,而是看起来很拉伸。
Run Code Online (Sandbox Code Playgroud)_writer = [AVAssetWriter assetWriterWithURL:url fileType:AVFileTypeQuickTimeMovie error:nil]; NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey, [NSNumber numberWithInt: 320], AVVideoWidthKey, [NSNumber numberWithInt: 320], AVVideoHeightKey, nil]; _videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:settings]; [_writer addInput:_videoInput];
有人可以帮助我解决视频播种问题吗?提前致谢。
objective-c avfoundation ios avassetwriter avvideocomposition
我正在开发一个个人iOS项目,需要通过4G连接上传到后端的全屏视频(长度为15秒).虽然我可以很好地拍摄视频,但文件的输出大小达到30MB,这让我觉得在压缩时我做了一些严重的错误.下面是我用来设置AssetWriter的代码:
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections
{
NSLog(@"Started Recording! *******************");
self.movieWriter = [AVAssetWriter assetWriterWithURL:fileURL fileType:AVFileTypeMPEG4 error:nil];
[self.movieWriter setShouldOptimizeForNetworkUse:YES];
NSDictionary *videoCleanApertureSettings = @{
AVVideoCleanApertureWidthKey: [NSNumber numberWithFloat:self.view.frame.size.width],
AVVideoCleanApertureHeightKey: [NSNumber numberWithFloat:self.view.frame.size.height],
AVVideoCleanApertureHorizontalOffsetKey: [NSNumber numberWithInt:10],
AVVideoCleanApertureVerticalOffsetKey: [NSNumber numberWithInt:10],
};
NSDictionary *videoCompressionSettings = @{
AVVideoAverageBitRateKey: [NSNumber numberWithFloat:5000000.0],
AVVideoMaxKeyFrameIntervalKey: [NSNumber numberWithInteger:1],
AVVideoProfileLevelKey: AVVideoProfileLevelH264Baseline30,
AVVideoCleanApertureKey: videoCleanApertureSettings,
};
NSDictionary *videoSettings = @{AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: [NSNumber numberWithFloat:self.view.frame.size.width],
AVVideoHeightKey: [NSNumber numberWithFloat:self.view.frame.size.height],
AVVideoCompressionPropertiesKey: videoCompressionSettings,
};
self.movieWriterVideoInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
self.movieWriterVideoInput.expectsMediaDataInRealTime = YES;
[self.movieWriter addInput:self.movieWriterVideoInput];
NSDictionary *audioSettings …Run Code Online (Sandbox Code Playgroud) 我有一个中等复杂的 AVAssetWriterInput 设置,我可以使用它在录制时翻转相机。基本上运行两个会话,当用户点击翻转相机时,我会断开会话 1 与输出的连接并附加会话 2。
这真的很棒。我可以导出视频并且播放得很好。
现在,我尝试对生成的视频执行更高级的操作,但突然出现了一些问题,特别是导出的 AVAsset 内部的 AVAssetTrack 略有不匹配(始终小于 1 帧)。具体来说,我正在尝试这样做:https://www.raywenderlich.com/6236502-avfoundation-tutorial-adding-overlays-and-animations-to-videos,但很多时候最终都是全黑的帧,有时在视频的头部,有时在视频的尾部,出现一瞬间。时间各不相同,但总是小于一帧(参见下面的日志,1/30或0.033333333s)
我进行了一些来回调试,并设法使用我的录像机录制了一个视频,该视频始终产生尾随黑帧,但使用教程代码我无法创建产生尾随黑帧的视频。我在教程代码中添加了一些类似的日志记录(与下面粘贴的内容相同),我看到增量不超过 2/100 秒。所以最多大约 1 帧的 1/10。有一次甚至是完美的 0。
所以我现在的感觉是,正在发生的事情是我录制视频,两个 assetInput 都开始吞噬数据,然后当我说“停止”时,它们就停止了。视频输入在最后一个完整帧处停止,音频输入也类似。但由于音频输入的采样率比视频高得多,因此它们没有完美同步,最终得到的音频比视频多。这不是问题,直到我用两个轨道合成一个资产,然后合成引擎认为我的意思是“是的,实际上所有轨道都使用 100% 的时间,即使存在不匹配”,这会导致黑屏。
(编辑:这基本上就是发生的事情 - https://blender.stackexchange.com/questions/6268/audio-track-and-video-track-are-not-the-same-length)
我认为正确的解决方案是,不要担心构图结构和时间安排并确保一切正常,而是让捕获的音频和视频尽可能匹配。理想情况下为 0,但我对 1/10 帧左右的任何内容都可以。
所以我的问题是:如何使两个 AVAssetWriterInput(一个音频和一个视频)附加到 AVAssetWriter 上更好地排列?某处有设置吗?我是否搞乱了帧速率?我应该将导出的资源修剪为视频轨道的长度吗?停止录制时可以复制最后捕获的帧吗?我可以让输入在不同时间停止 - 基本上让音频先停止,然后等待视频“赶上”,然后停止视频吗?还有别的事吗?我在这里不知所措:|
我的记录
BUFFER | VIdeo SETTINGS: Optional(["AVVideoCompressionPropertiesKey": {
AllowFrameReordering = 1;
AllowOpenGOP = 1;
AverageBitRate = 7651584;
**ExpectedFrameRate = 30;**
MaxKeyFrameIntervalDuration = 1;
MaxQuantizationParameter = 41;
MinimizeMemoryUsage = 1;
Priority = 80;
ProfileLevel = "HEVC_Main_AutoLevel";
RealTime = …Run Code Online (Sandbox Code Playgroud) 我使用glReadPixels抓取我的opengl场景的屏幕截图,然后在IOS 4上使用AVAssetWriter将它们转换为视频.我的问题是我需要将alpha通道传递给视频,该视频只接受kCVPixelFormatType_32ARGB和glReadPixels检索RGBA.所以基本上我需要一种方法将我的RGBA转换为ARGB,换句话说,首先放置alpha字节.
int depth = 4;
unsigned char buffer[width * height * depth];
glReadPixels(0,0,width, height, GL_RGBA, GL_UNSIGNED_BYTE, &buffer);
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, &buffer), width*height*depth, NULL );
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
CGImageRef image = CGImageCreate(width, height, 8, 32, width*depth, CGColorSpaceCreateDeviceRGB(), bitmapInfo, ref, NULL, true, kCGRenderingIntentDefault);
UIWindow* parentWindow = [self window];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options, &pxbuffer);
NSParameterAssert(status == kCVReturnSuccess);
NSParameterAssert(pxbuffer …Run Code Online (Sandbox Code Playgroud) 我很难理解如何使用AVAssetWriter将动态JPEG流以30fps转换为视频文件.我没有得到的部分是[adapter appendPixelBuffer:buffer withPresentationTimeresentTime]方法.
如果我想输出30fps mpeg4视频,如何计算withPresentationTime值?
视频源是一台实时流式传输30fps动态JPEG的摄像机.
欣赏任何想法.
谢谢
avassetwriter ×10
ios ×7
objective-c ×5
avfoundation ×4
iphone ×4
video ×2
argb ×1
compression ×1
core-image ×1
core-video ×1
opengl-es ×1
rgba ×1
swift ×1
textures ×1