NSArray de UIImages a error de video tiene distorsión en la salida

Soy relativamente nuevo en la progtwigción y, aunque estoy bien con las funciones normales, sin embargo, soy completamente nuevo en la edición de video

Entonces, he logrado encontrar un código en línea para hacer los trabajos que se muestran a continuación:

- (void)writeImagesAsMovie:(NSArray *)array { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDirectory, YES); NSString *documentDirectory = [paths objectAtIndex:0]; NSString *saveLocation = [documentDirectory stringByAppendingString:@"/temp.mov"]; if ([[NSFileManager defaultManager] fileExistsAtPath:saveLocation]) { [[NSFileManager defaultManager] removeItemAtPath:saveLocation error:NULL]; } UIImage *first = [array objectAtIndex:0]; CGSize frameSize = first.size; NSError *error = nil; AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL: [NSURL fileURLWithPath:saveLocation] fileType:AVFileTypeQuickTimeMovie error:&error]; if(error) { NSLog(@"error creating AssetWriter: %@",[error description]); } NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey, [NSNumber numberWithInt:frameSize.width], AVVideoWidthKey, [NSNumber numberWithInt:frameSize.height], AVVideoHeightKey, nil]; AVAssetWriterInput *writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings]; NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init]; [attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]; [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey]; [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey]; AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:attributes]; [videoWriter addInput:writerInput]; // fixes all errors writerInput.expectsMediaDataInRealTime = YES; //Start a session: [videoWriter startWriting]; [videoWriter startSessionAtSourceTime:kCMTimeZero]; CVPixelBufferRef buffer = NULL; buffer = [self pixelBufferFromCGImage:[first CGImage]]; BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero]; if (result == NO) //failes on 3GS, but works on iphone 4 NSLog(@"failed to append buffer"); if(buffer) { CVBufferRelease(buffer); } //int reverseSort = NO; NSArray *newArray = array; int fps = 10; int i = 0; for (UIImage *image in newArray) { [NSThread sleepForTimeInterval:0.02]; if (adaptor.assetWriterInput.readyForMoreMediaData) { i++; CMTime frameTime = CMTimeMake(1, fps); CMTime lastTime = CMTimeMake(i, fps); CMTime presentTime = CMTimeAdd(lastTime, frameTime); UIImage *imgFrame = image;//[UIImage imageWithContentsOfFile:filePath] ; buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]]; BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime]; if (result == NO) //failes on 3GS, but works on iphone 4 { NSLog(@"failed to append buffer"); NSLog(@"The error is %@", [videoWriter error]); [NSThread sleepForTimeInterval:0.5]; } if(buffer) { CVBufferRelease(buffer); } } else { NSLog(@"error"); i--; } } //Finish the session: [writerInput markAsFinished]; [videoWriter finishWriting]; CVPixelBufferPoolRelease(adaptor.pixelBufferPool); NSLog(@"Movie created successfully"); } - (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image { NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil]; CVPixelBufferRef pxbuffer = NULL; CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image), CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, &pxbuffer); CVPixelBufferLockBaseAddress(pxbuffer, 0); void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer); CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image), CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace, kCGImageAlphaNoneSkipFirst); CGContextConcatCTM(context, CGAffineTransformMakeRotation(0)); // CGAffineTransform flipVertical = CGAffineTransformMake( // 1, 0, 0, -1, 0, CGImageGetHeight(image) // ); // CGContextConcatCTM(context, flipVertical); // CGAffineTransform flipHorizontal = CGAffineTransformMake( // -1.0, 0.0, 0.0, 1.0, CGImageGetWidth(image), 0.0 // ); // // CGContextConcatCTM(context, flipHorizontal); CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); CGColorSpaceRelease(rgbColorSpace); CGContextRelease(context); CVPixelBufferUnlockBaseAddress(pxbuffer, 0); return pxbuffer; } 

Pero el problema que estoy teniendo es que la salida del video es algo corrupto (funciona aunque tiene líneas divertidas que se muestran a continuación: introduzca la descripción de la imagen aquí

Estaría muy agradecido por cualquier ayuda

Muchas gracias

Thomas

He estado viendo problemas con el hardware de encoding de video H264 donde puede dañar la input que no coincide con una relación de aspecto conocida. Por ejemplo, mis testings muestran que si una dimensión de video es menor que 128 píxeles, el video no codificará.

Lo que he visto funcionar es 128×128, 192×128, 240×160, 480×320, y otros.

Consulte esta página en relación de aspecto.

PS Es probable que desee utilizar el AVAssetWriterInputPixelBufferAdaptor ya que contiene un grupo de almacenamiento intermedio de píxeles que puede usar a través de CVPixelBufferPoolCreatePixelBuffer() . Además, querrá assert(adaptor.pixelBufferPool); después de llamar a startSessionAtSourceTime para asegurarse de que su adaptador puede escribir al escritor.