Developer on camera. Video
Front cameras on the iPad and iPhone gave birth to a new round of ideas from the creators of momentary applications. I also did a little research on dual-chamber phones and invite you to click on the button who cares.

Video capture in iOS 4.3+ is as simple as an orange.
Four calls - and you are the owner of the pixels received from any of the two cameras iPhone.
A little bit of code, designers do not read
We start our HabrahabrView
@class CaptureSessionManager;
@interface HabrahabrView : UIView {
CaptureSessionManager *captureFront;
CaptureSessionManager *captureBack;
UIImageView *face;
}
In the body of the class we introduce the mandatory function captureOutput, where pictures from the video camera will come 20 times per second.
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, 0);
// Get the number of bytes per row for the pixel buffer
// void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
// Get the number of bytes per row for the pixel buffer
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
// Get the pixel buffer width and height
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
unsigned char* pixel = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer);
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
CGContextRef context=CGBitmapContextCreate(pixel, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
CGImageRef image=CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIImage *resultUIImage=[UIImage imageWithCGImage:image];
CGImageRelease(image);
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
[resultUIImage retain];
[self performSelectorOnMainThread:@selector(cameraCaptureGotFrame:)
withObject:resultUIImage waitUntilDone:NO];
}
- (void) cameraCaptureGotFrame:(UIImage*)image
{
face.image = [self fixOrientation:image];
// decrement ref count
[image release];
}
Now that all the preliminary work is finished, we start the picture on the screen where our video will be displayed
face = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 58, 70)];
[self addSubview:face];
That's how we connect the rear camera
[self setCaptureBack:[[[CaptureSessionManager alloc] init] autorelease]];
[[self captureBack] addVideoInput:2 PView:self];
[[self captureBack] addVideoPreviewLayer];
[[[self captureBack] captureSession] setSessionPreset:AVCaptureSessionPresetLow];
And so the front
[self setCaptureFront:[[[CaptureSessionManager alloc] init] autorelease]];
[[self captureFront] addVideoInput:1 PView:self];
[[self captureFront] addVideoPreviewLayer];
[[[self captureFront] captureSession] setSessionPreset:AVCaptureSessionPresetLow];
Let's make all the functions in a separate class.
#import "CaptureSessionManager.h"
@implementation CaptureSessionManager
@synthesize captureSession;
@synthesize previewLayer;
- (id)init {
if ((self = [super init])) {
[self setCaptureSession:[[AVCaptureSession alloc] init]];
}
return self;
}
- (void)addVideoPreviewLayer {
[self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]];
[[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];
}
- (void)addVideoInput:(int)camType PView:(HabrahabrView*) habraview {
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *videoDevice = nil;
NSInteger side = (camType==1) ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;
for (AVCaptureDevice *device in videoDevices)
{
if (device.position == side)
{
videoDevice = device;
break;
}
}
if (videoDevice == nil) {
videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
if (videoDevice) {
NSError *error;
AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if (!error) {
if ([[self captureSession] canAddInput:videoIn])
[[self captureSession] addInput:videoIn];
else
NSLog(@"Couldn't add video input");
// Set the output
AVCaptureVideoDataOutput* videoOutput = [[AVCaptureVideoDataOutput alloc] init];
// create a queue to run the capture on
dispatch_queue_t captureQueue=dispatch_queue_create("catpureQueue", NULL);
// setup our delegate
[videoOutput setSampleBufferDelegate:habraview queue:captureQueue];
// configure the pixel format
videoOutput.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey,
nil];
if ([[self captureSession] canAddOutput:videoOutput])
[[self captureSession] addOutput:videoOutput];
else
NSLog(@"Couldn't add video ouput");
}
else
NSLog(@"Couldn't create video input");
}
else
NSLog(@"Couldn't create video capture device");
}
- (void)dealloc {
[[self captureSession] stopRunning];
[previewLayer release], previewLayer = nil;
[captureSession release], captureSession = nil;
[super dealloc];
}
@end
Work with cameras
Turn on the front camera
[[captureFront captureSession] startRunning];
Everything works. As you can see from the code, the video can be pulled in three resolutions. I choose the smallest AVCaptureSessionPresetLow (approximately 144 by 192 pixels) for speed. For our needs, this is enough, at the same time, and the image filter is free.
How to turn on the rear camera now? Stop the front and turn on the back
[[captureFront captureSession] stopRunning];
[[captureBack captureSession] startRunning];
I immediately wanted to include both. Alas. Impossible. I tried to quickly switch cameras, but there is a delay of about a third of a second, which causes nothing but irritation.
The dream of overlaying two images online had to be killed.
Fruit
But do not kill the dream of some stupid application. I decided to quickly create a fruit shutter - the image from the front camera is real, the oranges are virtual.
Oranges take turns falling onto the screen. They must be taken by mouth and eaten. Whoever eats 7 oranges faster is a prize.
It remains to write a mouth recognition procedure.
Recognizing the mouth is a primitive lesson, even I, a person falling into longing from the words of OOP, OpenSiVi, made this function quickly. Using neither OOP nor OpenSiVi.
Hint - You know the position of the orange and dance from it.
Yeah, the attentive reader will exclaim - the recognition procedure is debugged exclusively on the author when lighting his workplace. You are right, but judging by the photos of users, the application works successfully from China to Brazil, from offices to apartments.
Of course, there was a great temptation to sneak a photo of the user at the time of eating the 7th orange. I am always tempted, because they may not happen again. Calm For lovers of morality, I added a button - Allow to send your photo. The default is off.
I send a small picture of a player measuring 58 by 70 and secretly admire. Very funny pictures come across. I laugh at times for 3 minutes. There are also pretty people.
For God's sake, do not chat about photos, keep corporate secrets.
I completely forgot. My record is 12 seconds. I'm getting ready for the Olympics.
See you in London, friends.