gpt4 book ai didi

ios - AVAssetWriter 和 AVAssetWriterInputPixelBufferAdaptor appendingPixelBuffer 组合失败

转载 作者:行者123 更新时间:2023-12-01 16:54:11 37 4
gpt4 key购买 nike

我正在尝试使用为 encoding asset writer 提供的示例的组合。以及 pixelBufferFromCGImage 提供的样本在我正在导出的 AVAsset 上覆盖 UIImage。

问题是,尽管此调用的 True 结果

[adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];

导出的 avasset 已损坏,产生意外的大小,随后访问它失败并显示“此媒体可能已损坏”。

如果我避免尝试使用 appendPixelBuffer 调用,则导出本身是成功的。但是,将它定位在调度队列之前或其中会产生相同的故障。

希望不要在此处重复发布,但此处堆栈溢出中的其他示例似乎并未解决此特定组合故障。谢谢,代码如下

导出编码 :
 AVAsset *sourceAsset = [AVAsset assetWithURL:outputUrl];

NSError *error = nil;

NSString *fileName = [NSString stringWithFormat:@"non_transform_%f.mov", [[NSDate date] timeIntervalSince1970]];
NSString *combinedPath = [NSString stringWithFormat:@"file://localhost%@/%@", [[GroupDiskManager sharedManager] getFolderPath], fileName];

NSURL *outputURL = [NSURL URLWithString:combinedPath];
NSLog(@"combined path: %@", combinedPath);

AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:outputURL fileType:AVFileTypeQuickTimeMovie error:&error];


AVAssetTrack *videoTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *audioTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];


NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:1280], AVVideoWidthKey,
[NSNumber numberWithInt:720], AVVideoHeightKey,
nil];

AVAssetWriterInput* videoWriterInput = [[AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings] retain];






NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:1280] forKey:(NSString*)kCVPixelBufferWidthKey];
[attributes setObject:[NSNumber numberWithUnsignedInt:720] forKey:(NSString*)kCVPixelBufferHeightKey];


AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput
sourcePixelBufferAttributes:attributes];


NSParameterAssert(videoWriterInput);
NSParameterAssert([videoWriter canAddInput:videoWriterInput]);
videoWriterInput.expectsMediaDataInRealTime = NO;
[videoWriter addInput:videoWriterInput];

NSError *aerror = nil;

NSDictionary *videoOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
AVAssetReaderTrackOutput *asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack outputSettings:videoOptions];

AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:sourceAsset error:&aerror];
[reader addOutput:asset_reader_output];



AVAssetWriterInput* audioWriterInput = [[AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:nil] retain];
AVAssetReader *audioReader = [[AVAssetReader assetReaderWithAsset:sourceAsset error:&error] retain];




AVAssetReaderOutput *audioReaderOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:nil];
[audioReader addOutput:audioReaderOutput];
NSParameterAssert(audioWriterInput);
NSParameterAssert([videoWriter canAddInput:audioWriterInput]);
audioWriterInput.expectsMediaDataInRealTime = YES;
[videoWriter addInput:audioWriterInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
[reader startReading];


CVPixelBufferRef buffer = [ImageToMovieManager pixelBufferFromCGImage:[UIImage imageNamed:@"234_1280x720_3.jpg"].CGImage size:CGSizeMake(1280, 720)];
BOOL theResult = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];

if (theResult == NO) //failes on 3GS, but works on iphone 4
NSLog(@"failed to append buffer");

if(buffer) {
CVBufferRelease(buffer);
}




dispatch_queue_t _processingQueue = dispatch_queue_create("_processingQueue", NULL);
[videoWriterInput requestMediaDataWhenReadyOnQueue:_processingQueue usingBlock:
^{
NSLog(@"requestMediaDataWhenReadyOnQueue");

[self retain];

while ([videoWriterInput isReadyForMoreMediaData]) {



CMSampleBufferRef sampleBuffer;
if ([reader status] == AVAssetReaderStatusReading &&
(sampleBuffer = [asset_reader_output copyNextSampleBuffer])) {

BOOL result = [videoWriterInput appendSampleBuffer:sampleBuffer];
CFRelease(sampleBuffer);

if (!result) {
NSLog(@" result == nil Cancel!");
NSLog(@"videoWriter.error: %@", videoWriter.error);
[reader cancelReading];
break;

}
} else {
NSLog(@"[videoWriterInput markAsFinished]");

[videoWriterInput markAsFinished];

switch ([reader status]) {
case AVAssetReaderStatusReading:
NSLog(@"reading");
// the reader has more for other tracks, even if this one is done
break;

case AVAssetReaderStatusCompleted:
NSLog(@"AVAssetReaderStatusCompleted");

[audioReader startReading];
dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
[audioWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^
{

while (audioWriterInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer;
if ([audioReader status] == AVAssetReaderStatusReading &&
(nextBuffer = [audioReaderOutput copyNextSampleBuffer])) {
if (nextBuffer) {
[audioWriterInput appendSampleBuffer:nextBuffer];
}
}else{
[audioWriterInput markAsFinished];
switch ([audioReader status]) {
case AVAssetReaderStatusCompleted:
NSLog(@"AVAssetReaderStatusCompleted!!");
[videoWriter finishWriting];
[VideoManager videoSavedWithURL:outputURL withError:(NSError *)error];
break;
}
}
}

}
];
break;

case AVAssetReaderStatusFailed:
NSLog(@"AVAssetReaderStatusFailed");
[videoWriter cancelWriting];
break;
}
break;
}
}
}

];

pixelBufferFromCGImageCode
 CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width,
frameSize.height, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, (CFDictionaryRef) options,
&pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);


CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, frameSize.width,
frameSize.height, 8, 4*frameSize.width, rgbColorSpace,
kCGImageAlphaNoneSkipLast);

CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);

CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

return pxbuffer;

最佳答案

至少,pixelFormat 应该指定为 kCVPixelFormatType_32BGRA 而不是 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange。

关于ios - AVAssetWriter 和 AVAssetWriterInputPixelBufferAdaptor appendingPixelBuffer 组合失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13333798/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com