Last active
December 19, 2015 13:38
-
-
Save eralston/5963263 to your computer and use it in GitHub Desktop.
A sub-class of AVCaptureSession that adds a few helper properties for simplifying access to device hardware and add capabilities like flipping between the front and back camera.
This file contains 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
// | |
// SimpleCaptureSession.h | |
// | |
// Copyright (c) 2013 Erik Ralston | |
// | |
// MIT License | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE. | |
// | |
#import <AVFoundation/AVFoundation.h> | |
/// | |
/// A class that adds several helpers to AVCapture session to make video recording and camera management easier | |
/// | |
@interface SimpleCaptureSession : AVCaptureSession | |
// Devices | |
@property (nonatomic, readonly) AVCaptureDevice *rearCameraDevice; | |
@property (nonatomic, readonly) AVCaptureDevice *frontCameraDevice; | |
@property (nonatomic, readonly) AVCaptureDevice *audioDevice; | |
// Helpers | |
- (BOOL)isFrontCameraSupported; | |
// Methods for safely adding devices (and logging when things go wrong) | |
- (void)tryAddInput:(AVCaptureInput *)input; | |
- (AVCaptureDeviceInput *)tryAddDeviceAsInput:(AVCaptureDevice *)device; | |
// Methods for easily adding devices as inputs | |
- (AVCaptureDeviceInput *)addRearCameraAsInput; | |
- (void)removeRearCameraAsInput; | |
- (AVCaptureDeviceInput *)addFrontCameraAsInput; | |
- (void)removeFrontCameraAsInput; | |
- (AVCaptureDeviceInput *)addAudioAsInput; | |
// Methods for easily adding output | |
- (void)tryAddOutput:(AVCaptureOutput *)output; | |
- (AVCaptureMovieFileOutput *)addFileOutput; | |
// Methods for mixing input and output | |
- (void)flipCamera; | |
@end |
This file contains 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
// | |
// SimpleCaptureSession.m | |
// | |
// Copyright (c) 2013 Erik Ralston | |
// | |
// MIT License | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE. | |
// | |
#import "SimpleCaptureSession.h" | |
@interface SimpleCaptureSession() | |
{ | |
// Fields for holding onto inputs for devices | |
AVCaptureDeviceInput *_rearCameraDeviceInput; | |
AVCaptureDeviceInput *_frontCameraDeviceInput; | |
AVCaptureDeviceInput *_audioDeviceInput; | |
} | |
@end | |
@implementation SimpleCaptureSession | |
#pragma mark - Input Device Properties | |
/// | |
/// Gets the rear camera device | |
/// | |
- (AVCaptureDevice *)rearCameraDevice | |
{ | |
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; | |
} | |
/// | |
/// Gets the front camera device | |
/// NOTE: Returns nil if no front camera found | |
/// | |
- (AVCaptureDevice *)frontCameraDevice | |
{ | |
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; | |
for (AVCaptureDevice *device in devices) { | |
// Check if this is the front-facing camera | |
if([device position] == AVCaptureDevicePositionFront) | |
{ | |
// if we found it, then add it and return it | |
return device; | |
} | |
} | |
// if we didn't find it, return nil | |
return nil; | |
} | |
/// | |
/// Gets the microphone device | |
/// | |
- (AVCaptureDevice *)audioDevice | |
{ | |
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; | |
} | |
#pragma mark - Helper Methods | |
/// | |
/// Returns YES if the front camera is supported by the current device; otherwise, returning NO | |
/// | |
- (BOOL)isFrontCameraSupported | |
{ | |
return [self frontCameraDevice] != nil; | |
} | |
/// | |
/// Attempts to add the given input, logging an error if unable | |
/// | |
- (void)tryAddInput:(AVCaptureInput *)input | |
{ | |
if ([self canAddInput:input]) | |
[self addInput:input]; | |
else | |
NSLog(@"Couldn't add input device %@", input); | |
} | |
/// | |
/// Tries to add the given device as an input, logging errors if problems occur | |
/// | |
- (AVCaptureDeviceInput *)tryAddDeviceAsInput:(AVCaptureDevice *)device | |
{ | |
if (device) { | |
NSError *error; | |
AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; | |
if (!error) { | |
[self tryAddInput:videoIn]; | |
return videoIn; | |
} | |
else | |
NSLog(@"Error trying to capture for device %@ with error %@", device, error); | |
} | |
else | |
NSLog(@"Nil device passed, could not add"); | |
return nil; | |
} | |
/// | |
/// Adds the video device as an input to the AVCaptureSession | |
/// | |
- (AVCaptureDeviceInput *)addRearCameraAsInput | |
{ | |
// Setup Video Capture | |
_rearCameraDeviceInput = [self tryAddDeviceAsInput:self.rearCameraDevice]; | |
return _rearCameraDeviceInput; | |
} | |
/// | |
/// Removes the rear camera as an input | |
/// | |
- (void)removeRearCameraAsInput | |
{ | |
[self removeInput:_rearCameraDeviceInput]; | |
_rearCameraDeviceInput = nil; | |
} | |
/// | |
/// Tries to add the front-facing camera as an input for this device, | |
/// | |
- (AVCaptureDeviceInput *)addFrontCameraAsInput | |
{ | |
// Try to find the front facing camera | |
AVCaptureDevice *frontFacingCameraDevice = [self frontCameraDevice]; | |
// If we have a front-facing camera, then add it; otherwise, add the read camera | |
if(frontFacingCameraDevice) | |
_frontCameraDeviceInput = [self tryAddDeviceAsInput:frontFacingCameraDevice]; | |
else | |
_frontCameraDeviceInput = [self addRearCameraAsInput]; | |
return _frontCameraDeviceInput; | |
} | |
/// | |
/// Removes the front camera as an input | |
/// | |
- (void)removeFrontCameraAsInput | |
{ | |
[self removeInput:_frontCameraDeviceInput]; | |
_frontCameraDeviceInput = nil; | |
} | |
/// | |
/// Adds the audio device as an input to the AVCaptureSession | |
/// | |
- (AVCaptureDeviceInput *)addAudioAsInput | |
{ | |
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; | |
return [self tryAddDeviceAsInput:audioDevice]; | |
} | |
#pragma mark - Methods for Easy Output | |
/// | |
/// Adds an output device, only if able, then logging if failed | |
/// | |
- (void)tryAddOutput:(AVCaptureOutput *)output | |
{ | |
if([self canAddOutput:output]) | |
[self addOutput:output]; | |
else | |
NSLog(@"Unable to add output %@", output); | |
} | |
/// | |
/// Adds a capture movie file output to the current session | |
/// | |
- (AVCaptureMovieFileOutput *)addFileOutput | |
{ | |
AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; | |
[self tryAddOutput:movieFileOutput]; | |
return movieFileOutput; | |
} | |
#pragma mark - Methods for Input & Output | |
/// | |
/// Flips the front and rear-facing camera, based on which one is currently in use | |
/// | |
- (void)flipCamera | |
{ | |
if(_frontCameraDeviceInput) | |
{ | |
[self removeFrontCameraAsInput]; | |
[self addRearCameraAsInput]; | |
} else { | |
[self removeRearCameraAsInput]; | |
[self addFrontCameraAsInput]; | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment