Created
January 30, 2016 21:21
-
-
Save rfistman/93d114959ae83ebabcda to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "AppDelegate.h" | |
#import <AVFoundation/AVFoundation.h> | |
@interface AppDelegate () | |
@property (nonatomic) AVAssetWriter *writer; | |
@property (nonatomic) AVAssetWriterInputPixelBufferAdaptor *adaptor; | |
@property (nonatomic) dispatch_queue_t q; | |
@end | |
@implementation AppDelegate | |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | |
NSString *path = @"/Users/gchilds/Desktop/foo.mov"; | |
NSURL *fileUrl = [NSURL fileURLWithPath:path]; | |
[[NSFileManager defaultManager] removeItemAtURL:fileUrl error:nil]; | |
NSError *error; | |
AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:fileUrl fileType:AVFileTypeQuickTimeMovie error:&error]; | |
NSDictionary* vidOpts = [NSDictionary dictionaryWithObjectsAndKeys: | |
AVVideoCodecH264, AVVideoCodecKey, // the only supported codec. perfectly natural. | |
[NSNumber numberWithInt:640], AVVideoWidthKey, | |
[NSNumber numberWithInt:480], AVVideoHeightKey, | |
nil]; | |
AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:vidOpts]; | |
NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: | |
[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil]; | |
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput | |
sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary]; | |
//writer.movieFragmentInterval = CMTimeMake(5, 1); | |
writer.movieFragmentInterval = CMTimeMakeWithSeconds(10, 1000000000); | |
[writer addInput:writerInput]; | |
if (![writer startWriting]) { | |
NSLog(@"BOO"); | |
} | |
[writer startSessionAtSourceTime:kCMTimeZero]; | |
self.writer = writer; | |
self.adaptor = adaptor; | |
self.q = dispatch_queue_create("blerg", DISPATCH_QUEUE_SERIAL); | |
UIImage *image = [UIImage imageNamed:@"Cosmos09.jpg"]; | |
__block int i = 0; | |
CVPixelBufferRef img = [AppDelegate pixelBufferFromCGImage:image.CGImage]; | |
[writerInput requestMediaDataWhenReadyOnQueue:self.q usingBlock:^{ | |
if (![adaptor appendPixelBuffer:img withPresentationTime:CMTimeMake(i++, 30)]) { | |
NSLog(@"zzz %@", writer.error); | |
} | |
}]; | |
// [adaptor appendPixelBuffer:[AppDelegate pixelBufferFromCGImage:image.CGImage] withPresentationTime:kCMTimeZero]; | |
if (false) { | |
[writer finishWritingWithCompletionHandler:^{ | |
NSLog(@"fini"); | |
}]; | |
} | |
return YES; | |
} | |
+ (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image | |
{ | |
CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)); | |
NSDictionary *options = @{ | |
(__bridge NSString *)kCVPixelBufferCGImageCompatibilityKey: @(NO), | |
(__bridge NSString *)kCVPixelBufferCGBitmapContextCompatibilityKey: @(NO) | |
}; | |
CVPixelBufferRef pixelBuffer; | |
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width, | |
frameSize.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, | |
&pixelBuffer); | |
if (status != kCVReturnSuccess) { | |
return NULL; | |
} | |
CVPixelBufferLockBaseAddress(pixelBuffer, 0); | |
void *data = CVPixelBufferGetBaseAddress(pixelBuffer); | |
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); | |
CGContextRef context = CGBitmapContextCreate(data, frameSize.width, frameSize.height, | |
8, CVPixelBufferGetBytesPerRow(pixelBuffer), rgbColorSpace, | |
(CGBitmapInfo) kCGImageAlphaNoneSkipFirst); | |
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), | |
CGImageGetHeight(image)), image); | |
CGColorSpaceRelease(rgbColorSpace); | |
CGContextRelease(context); | |
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); | |
return pixelBuffer; | |
} | |
@end |
That does appear to fix the problem! Thank you!
Glad to be of help!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Raising the fragment interval seems to help - I'm not getting errors with 3 seconds.