How to use torch light in iPhone app? - iphone

I need to use iPhone Flash light in my app. But, while the user switch on the flash the camera does not take picture. How can i do this? Here i have attached my code. But, when i switch on the flash light, the camera takes picture.
AVCaptureDeviceInput *flashInput = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
[session addInput:flashInput];
[session addOutput:output];
[device unlockForConfiguration];
[output release];
[session commitConfiguration];
[session startRunning];
[self setTorchSession:session];
Where i am wrong in coding? Please help me. Thanks in advance.

I have a torch button in my app which uses the following 3 methods.
- (void)initialiseTorch {
if (!session) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
session = [[AVCaptureSession alloc] init];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
[session addInput:input];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[session addOutput:output];
[session startRunning];
[output release];
}
}
- (void)releaseTorch {
if (session) {
[session stopRunning];
[session release];
session = nil;
}
}
- (void) lightButtonPressed {
if (!session) {
[self initialiseTorch];
}
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[session beginConfiguration];
[device lockForConfiguration:nil];
if ([device torchMode] == AVCaptureTorchModeOn) {
[device setTorchMode:AVCaptureTorchModeOff];
} else {
[device setTorchMode:AVCaptureTorchModeOn];
}
[device unlockForConfiguration];
[session commitConfiguration];
}
The only difference I can see between our code is that you are also setting the Flash Mode. Also I configure my session, and then turn the torch on/off in a seperate beginConfiguration pass

check this...
- (void)torchOnOff: (BOOL) onOff
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
[device setTorchMode: onOff ? AVCaptureTorchModeOn : AVCaptureTorchModeOff];
[device unlockForConfiguration];
}
}

Related

iOS7 - Outputting frames with AVCaptureMetadataOutput?

I am trying to use the iOS7 QR reading functions in the AVFoundation framework using the following code:
-(void)setupCaptureSession_iOS7 {
self.session = [[AVCaptureSession alloc] init];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (!input)
{
NSLog(#"Error: %#", error);
return;
}
[session addInput:input];
//Turn on point autofocus for middle of view
[device lockForConfiguration:&error];
CGPoint point = CGPointMake(0.5,0.5);
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device unlockForConfiguration];
//Add the metadata output device
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
NSLog(#"%lu",(unsigned long)output.availableMetadataObjectTypes.count);
for (NSString *s in output.availableMetadataObjectTypes)
NSLog(#"%#",s);
//You should check here to see if the session supports these types, if they aren't support you'll get an exception
output.metadataObjectTypes = #[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeUPCECode];
output.rectOfInterest = CGRectMake(0, 0, 320, 480);
[session startRunning];
// Assign session to an ivar.
[self setSession:self.session];
}
This code obviously doesn't render the frames to the screen (yet). This is because, instead of using the AVCaptureVideoPreviewLayer class to display the preview, I need to display the frames as a UIImage (this is because I have want to display the frames multiple times on the view).
If I use AVCaptureVideoDataOutput as the output, I'm able to export the frames using by grabbing them from the captureOutput:didOutputSampleBuffer:fromConnection: callback. But I can't find an equivalent way to call get the frameBuffer when using AVCaptureMetadataOutput as the output.
Does anyone have any idea how to do this?

Strang flash behaver on AVCaptureDeviceInput

I use this code to get flash working on the video that i recorded
NSError *error = nil;
// Create the session
AVCaptureSession *session = [[AVCaptureSession alloc] init];
// Configure the session to produce lower resolution video frames, if your
// processing algorithm can cope. We'll specify medium quality for the
// chosen device.
session.sessionPreset = AVCaptureSessionPresetMedium;
// Find a suitable AVCaptureDevice
AVCaptureDevice *device = [AVCaptureDevice
defaultDeviceWithMediaType:AVMediaTypeVideo];
// Create a device input with the device and add it to the session.
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
[session addInput:input];
// Create a VideoDataOutput and add it to the session
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init] ;
[session addOutput:output];
// Configure your output.
dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
// Specify the pixel format
output.videoSettings =
[NSDictionary dictionaryWithObject:
[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
forKey:(id)kCVPixelBufferPixelFormatTypeKey];
[output setAlwaysDiscardsLateVideoFrames:YES];
// If you wish to cap the frame rate to a known value, such as 15 fps, set
//turn flash on
[session beginConfiguration];
BOOL lockAcquired = [device lockForConfiguration:&error];
if (!lockAcquired) {
// log err and handle...
} else {
if ([device hasTorch] && [device hasFlash]){
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
}
[device unlockForConfiguration];
[session commitConfiguration];
// Start the session running to start the flow of data
[session startRunning];
but there is an strange behavior when recording start , the flash turn on then turn off for less a second then permanently stay on , Did anyone know why and how i solve it ?
Try making AVCaptureSession *session and AVCaptureDeviceInput *input member variables of your class. They need to survive function scope

How to open camera with flash mode

I am developing a simple app in which i need to make my camera flash mode to be on continuously not only when capturing image. And the mode of operation should be camera not video recording. Is it possible ? If so than how. Please help me with some code
You can use the below method to toggle camera flash on and off.
- (void)toggleFlashlight
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (device.torchMode == AVCaptureTorchModeOff)
{
// Create an AV session
AVCaptureSession *session = [[AVCaptureSession alloc] init];
// Create device input and add to current session
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
[session addInput:input];
// Create video output and add to current session
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[session addOutput:output];
// Start session configuration
[session beginConfiguration];
[device lockForConfiguration:nil];
// Set torch to on
[device setTorchMode:AVCaptureTorchModeOn];
[device unlockForConfiguration];
[session commitConfiguration];
// Start the session
[session startRunning];
// Keep the session around
[self setAVSession:session];
[output release];
}
else
{
[AVSession stopRunning];
[AVSession release],
AVSession = nil;
}
}
You can also use the following method along with the display of camera,
- (void) toggleFlashlight {
// check if flashlight available
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
if (device.torchMode == AVCaptureTorchModeOff)
{
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
}
else
{
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
}
[device unlockForConfiguration];
}
}
}
Source
Use this for Swift 4
func toggleFlash() {
guard let device = AVCaptureDevice.default(for: AVMediaType.video)
else {return}
if device.hasTorch {
do {
try device.lockForConfiguration()
if device.torchMode == AVCaptureDevice.TorchMode.on {
device.torchMode = AVCaptureDevice.TorchMode.off
//AVCaptureDevice.TorchModeAVCaptureDevice.TorchMode.off
} else {
do {
try device.setTorchModeOn(level: 1.0)
} catch {
print(error)
}
}
device.unlockForConfiguration()
} catch {
print(error)
}
}
}

how to produce a light on shake gesture on iphone [duplicate]

I'm trying to make a flashlight app for my iPhone. I have an iPhone 4 and would like to utilize the LED on my iPhone for my project. Can anyone help me to get started with that?
Here is a shorter version you can now use to turn the LED on or off:
- (void)torchOnOff: (BOOL) onOff
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
[device setTorchMode: onOff ? AVCaptureTorchModeOn : AVCaptureTorchModeOff];
[device unlockForConfiguration];
}
}
UPDATE: (March 2015)
You can also set the brightness of the torch:
- (void)setTorchToLevel:(float)torchLevel
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
if (torchLevel <= 0.0) {
[device setTorchMode:AVCaptureTorchModeOff];
}
else {
if (torchLevel >= 1.0)
torchLevel = AVCaptureMaxAvailableTorchLevel;
BOOL success = [device setTorchModeOnWithLevel:torchLevel error:nil];
}
[device unlockForConfiguration];
}
}
Use the following:
AVCaptureSession * session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
[device unlockForConfiguration];
AVCaptureDeviceInput * flashInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (flashInput){
[session addInput:flashInput];
}
AVCaptureVideoDataOutput * output = [[AVCaptureVideoDataOutput alloc] init];
[session addOutput:output];
[output release];
[session commitConfiguration];
[session startRunning];
}
[self setTorchSession:session];
[session release];
(From a discussion on iPhoneDevSDK)

how can I make the torch/flash-on reliable when coming from multitask

When I leave the app and come back to it's 'on' sate sometimes it works fine by turning the torch/flash on but most of the time it either flashes or remains off.
AppDeligate.m
- (id) init {
torchState = TRUE;
if( (self=[super init] )) {
/// initialize flashlight
// test if this class even exists to ensure flashlight is turned on ONLY for iOS 4 and above
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
if (device.torchMode == AVCaptureTorchModeOff) {
NSLog(#"Setting up flashlight for later use...");
AVCaptureDeviceInput *flashInput = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
[device lockForConfiguration:nil];
[session addInput:flashInput];
[session addOutput:output];
[device unlockForConfiguration];
[output release];
[session commitConfiguration];
[session startRunning];
[self setTorchSession:session];
[session release];
}
}
}
}
return self;
}
- (void)toggleTorch {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
// For the first 4 to 5 times comming back from multiask this first if hits and works properly
if (torchState == TRUE && device.torchMode == AVCaptureTorchModeOff) {
NSLog(#"AVCaptureTorchModeOff setting On");
// On the 4th or 5th time it flashes and stays off or does nothing staying OFF
// even though the NSLog fires
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
} else if (torchState == TRUE && device.torchMode == AVCaptureTorchModeOn) {
// Sometimes this randomly fires and every time ErrorNotification fires too
NSLog(#"AVCaptureTorchModeOn");
if (AVCaptureSessionRuntimeErrorNotification) {
NSLog(#"ERROR");
// Try to force but doesn't do anything
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
}
} else {
NSLog(#"ALL IS OFF");
// when torch is in the off state it returns off as it should
torchState = FALSE;
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
}
[device unlockForConfiguration];
}
-(void) applicationDidEnterForeground:(UIApplication*)application {
[self toggleTorch];
}
The only thing I haven't included in code is a touch even that calls toggleTorch for on/off. That piece works great so again, what I'm testing here is turning it on at launch aka DidEnterForeground as well as when the app is returned to from a multitask session.
I would change 2 things:
1. add it to ApplicationDidBecomeActive
2. don't use toggle torch but set the state you want it to be (so you won't turn it off twice or on twice...). So change the function to toggleTorchWithState...
That what I've done in one of my apps and that works perfectly.