मैं छवियों से वीडियो बनाने के लिए फ़ाइल में CGImages लिखने के लिए AVAssetWriter का उपयोग करने का प्रयास कर रहा हूं।AVAssetWriter Woes
मुझे यह सिम्युलेटर पर तीन अलग-अलग तरीकों से सफलतापूर्वक काम करने के लिए मिला है, लेकिन प्रत्येक विधि आईओएस 4 पर आईफोन 4 चलाने में विफल रही है।
यह सब पिक्सेल बफर के साथ करना है।
मेरी पहली विधि केवल पूल का उपयोग किये बिना पिक्सेल बफर बनाने की आवश्यकता थी। यह काम करता है, लेकिन डिवाइस पर काम करने के लिए बहुत स्मृति गहन है।
मेरी दूसरी विधि अनुशंसित AVAssetWriterInputPixelBufferAdaptor का उपयोग करना था और उसके बाद एडाप्टर पिक्सेलबफरपूल से पिक्सेल बफर खींचें CVPixelBufferPoolCreatePixelBuffer के साथ।
यह सिम्युलेटर पर भी काम करता है, लेकिन डिवाइस पर विफल रहता है क्योंकि एडाप्टर के पिक्सेल बफर पूल को आवंटित नहीं किया जाता है। मुझे कोई त्रुटि संदेश नहीं मिला।
आखिरकार, मैंने अपने पिक्सेल बफर पूल द्वारा CVPixelBufferPoolCreate के साथ बनाने का प्रयास किया। यह सिम्युलेटर में भी काम करता है लेकिन डिवाइस पर, जब तक मैं पिक्सेल बफर को एपेंड पिक्सेलबफर के साथ जोड़ने की कोशिश नहीं करता तब तक सब कुछ ठीक काम करता है जो हर बार विफल रहता है।
मुझे वेब पर इस पर बहुत कम जानकारी मिली है। मैंने अपने उदाहरणों को मेरे द्वारा प्राप्त किए गए उदाहरणों पर आधारित किया है, लेकिन अब दिनों के लिए कोई भाग्य नहीं है। अगर किसी को AVAssetWriter के साथ सफलतापूर्वक ऐसा करने का अनुभव है, तो कृपया एक नज़र डालें और मुझे बताएं कि क्या आप जगह से कुछ भी देखते हैं।
नोट: आप प्रयासों के ब्लॉक पर टिप्पणी देखेंगे।
पहले, सेटअप
- (BOOL) openVideoFile: (NSString *) path withSize:(CGSize)imageSize {
size = CGSizeMake (480.0, 320.0);//imageSize;
NSError *error = nil;
videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie
error:&error];
if (error != nil)
return NO;
NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:size.width], AVVideoCleanApertureWidthKey,
[NSNumber numberWithDouble:size.height], AVVideoCleanApertureHeightKey,
[NSNumber numberWithInt:10], AVVideoCleanApertureHorizontalOffsetKey,
[NSNumber numberWithInt:10], AVVideoCleanApertureVerticalOffsetKey,
nil];
NSDictionary *videoAspectRatioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:1], AVVideoPixelAspectRatioHorizontalSpacingKey,
[NSNumber numberWithInt:1],AVVideoPixelAspectRatioVerticalSpacingKey,
nil];
NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
//[NSNumber numberWithInt:960000], AVVideoAverageBitRateKey,
// [NSNumber numberWithInt:1],AVVideoMaxKeyFrameIntervalKey,
videoCleanApertureSettings, AVVideoCleanApertureKey,
videoAspectRatioSettings, AVVideoPixelAspectRatioKey,
//AVVideoProfileLevelH264Main31, AVVideoProfileLevelKey,
nil];
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
codecSettings,AVVideoCompressionPropertiesKey,
[NSNumber numberWithDouble:size.width], AVVideoWidthKey,
[NSNumber numberWithDouble:size.height], AVVideoHeightKey,
nil];
writerInput = [[AVAssetWriterInput
assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings] retain];
NSMutableDictionary * bufferAttributes = [[NSMutableDictionary alloc] init];
[bufferAttributes setObject: [NSNumber numberWithInt: kCVPixelFormatType_32ARGB]
forKey: (NSString *) kCVPixelBufferPixelFormatTypeKey];
[bufferAttributes setObject: [NSNumber numberWithInt: 480]
forKey: (NSString *) kCVPixelBufferWidthKey];
[bufferAttributes setObject: [NSNumber numberWithInt: 320]
forKey: (NSString *) kCVPixelBufferHeightKey];
//NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
//[bufferAttributes setObject: [NSNumber numberWithInt: 640]
// forKey: (NSString *) kCVPixelBufferWidthKey];
//[bufferAttributes setObject: [NSNumber numberWithInt: 480]
// forKey: (NSString *) kCVPixelBufferHeightKey];
adaptor = [[AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:nil] retain];
//CVPixelBufferPoolCreate (kCFAllocatorSystemDefault,NULL,(CFDictionaryRef)bufferAttributes,&pixelBufferPool);
//Create buffer pool
NSMutableDictionary* attributes;
attributes = [NSMutableDictionary dictionary];
int width = 480;
int height = 320;
[attributes setObject:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
[attributes setObject:[NSNumber numberWithInt:width] forKey: (NSString*)kCVPixelBufferWidthKey];
[attributes setObject:[NSNumber numberWithInt:height] forKey: (NSString*)kCVPixelBufferHeightKey];
CVReturn theError = CVPixelBufferPoolCreate(kCFAllocatorDefault, NULL, (CFDictionaryRef) attributes, &pixelBufferPool);
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
writerInput.expectsMediaDataInRealTime = YES;
//Start a session:
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
buffer = NULL;
lastTime = kCMTimeZero;
presentTime = kCMTimeZero;
return YES;
}
इसके बाद, दो तरीकों कि लेखक संलग्न करें और संलग्न करने के लिए पिक्सेल बफर पैदा करते हैं।
- (void) writeImageToMovie:(CGImageRef)image
{
if([writerInput isReadyForMoreMediaData])
{
// CMTime frameTime = CMTimeMake(1, 20);
// CMTime lastTime=CMTimeMake(i, 20); //i is from 0 to 24 of the loop above
// CMTime presentTime=CMTimeAdd(lastTime, frameTime);
buffer = [self pixelBufferFromCGImage:image];
BOOL success = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
if (!success) NSLog(@"Failed to appendPixelBuffer");
CVPixelBufferRelease(buffer);
presentTime = CMTimeAdd(lastTime, CMTimeMake(5, 1000));
lastTime = presentTime;
}
else
{
NSLog(@"error - writerInput not ready");
}
}
- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image
{
CVPixelBufferRef pxbuffer;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
if (pixelBufferPool == NULL) NSLog(@"pixelBufferPool is null!");
CVReturn status = CVPixelBufferPoolCreatePixelBuffer (NULL, pixelBufferPool, &pxbuffer);
/*if (pxbuffer == NULL) {
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, size.width,
size.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
&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,
kCGImageAlphaNoneSkipFirst);
//NSParameterAssert(context);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(90, 10, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
वाह, यह dissapointing है। किसी के पास कोई सुराग नहीं है? –