2010-07-06 118 views
44

我知道开启闪光灯并将其保持在iPhone 4上的唯一方法是打开摄像机。虽然我不太确定代码。这是我正在尝试:打开iPhone上的手电筒/闪光灯

-(IBAction)turnTorchOn { 
    AVCaptureSession *captureSession = [[AVCaptureSession alloc] init]; 
    AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    NSError *error = nil; 
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error]; 

    if (videoInput) { 
     [captureSession addInput:videoInput]; 

     AVCaptureVideoDataOutput* videoOutput = [[AVCaptureVideoDataOutput alloc] init]; 
     [videoOutput setSampleBufferDelegate:self queue:dispatch_get_current_queue()]; 

     [captureSession addOutput:videoOutput]; 

     [captureSession startRunning]; 

     videoCaptureDevice.torchMode = AVCaptureTorchModeOn; 
    } 
} 

有谁知道这是否会工作,或者我错过了什么? (我还没有测试iPhone 4,只是尝试一些新的API)。

感谢

回答

15

lockforConfiguration在你的代码,你宣布你的AVCaptureDevice是一个属性设置。

[videoCaptureDevice lockForConfiguration:nil]; 
18

见下一个更好的答案:https://stackoverflow.com/a/10054088/308315


老答案:

首先,在你的AppDelegate .h文件中:

#import <AVFoundation/AVFoundation.h> 

@interface AppDelegate : NSObject <UIApplicationDelegate> { 

    AVCaptureSession *torchSession; 

} 

@property (nonatomic, retain) AVCaptureSession * torchSession; 

@end 

然后在你的AppDe使节.m文件:

@implementation AppDelegate 

@synthesize torchSession; 

- (void)dealloc { 
    [torchSession release]; 

    [super dealloc]; 
} 

- (id) init { 
    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; 
} 

那么任何时候你想打开它,只是做这样的事情:

// 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]; 

    [device lockForConfiguration:nil]; 

    [device setTorchMode:AVCaptureTorchModeOn]; 
    [device setFlashMode:AVCaptureFlashModeOn]; 

    [device unlockForConfiguration]; 

} 

而对于关闭它类似:

// 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]; 

    [device lockForConfiguration:nil]; 

    [device setTorchMode:AVCaptureTorchModeOff]; 
    [device setFlashMode:AVCaptureFlashModeOff]; 

    [device unlockForConfiguration]; 
} 
+1

在appdelegate.m文件,您应该将'init'法的东西,如内容:'如果((自我= [超级的init])) {...}返回自我;' – Senseful 2011-04-28 06:05:48

+0

这太combursom,并保持会话消耗电池。从Tibidabo试试下面的方法 – doozMen 2013-02-27 15:42:47

69

这里有一个现在可以使用较短的版本打开或关闭灯光:

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
if ([device hasTorch]) { 
    [device lockForConfiguration:nil]; 
    [device setTorchMode:AVCaptureTorchModeOn]; // use AVCaptureTorchModeOff to turn off 
    [device unlockForConfiguration]; 
} 

UPDATE:(2015年3月)

与iOS 6.0和更高版本,可以使用下面的方法控制火炬的亮度或级别:

- (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]; 
    } 
} 

您可能还需要监视的返回值( success)从setTorchModeOnWithLevel:。如果您尝试将电平设置得太高而手电筒过热,则可能会失败。在这种情况下,将等级设置为AVCaptureMaxAvailableTorchLevel会将等级设置为考虑到割炬温度所允许的最高等级。

+2

这使我在尝试切换闪光灯时确实使事情变得更简单和更有反应。我曾经使用过iWasRobbed发布的方法,但它并没有很好的响应。 – 2012-01-02 02:50:42

+0

美女!发挥了魅力。 – 2012-03-17 04:51:55

35

iWasRobbed的回答很好,除了有一个AVCaptureSession一直在后台运行。在我的iPhone 4s上,根据仪器需要大约12%的CPU电量,所以我的应用程序在一分钟内耗电约1%。换句话说,如果设备准备进行AV捕捉,那么它并不便宜。

使用下面的代码我的应用程序每分钟需要0.187%的电量,所以电池的使用寿命要长5倍以上。

此代码适用于任何设备(在3GS(无闪存)和4s上都测试过)。在模拟器中测试4.3也是如此。

#import <AVFoundation/AVFoundation.h> 

- (void) turnTorchOn:(BOOL)on { 

    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice"); 
    if (captureDeviceClass != nil) { 
     AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
     if ([device hasTorch] && [device hasFlash]){ 

      [device lockForConfiguration:nil]; 
      if (on) { 
       [device setTorchMode:AVCaptureTorchModeOn]; 
       [device setFlashMode:AVCaptureFlashModeOn]; 
       torchIsOn = YES; 
      } else { 
       [device setTorchMode:AVCaptureTorchModeOff]; 
       [device setFlashMode:AVCaptureFlashModeOff]; 
       torchIsOn = NO;    
      } 
      [device unlockForConfiguration]; 
     } 
    } 
} 
+0

此版本适用于哪些版本的ios? – Mona 2012-04-08 10:05:31

+1

它应该可以工作,即它应该从5.0开始工作,并且它不应该低于此值。 – Tibidabo 2012-04-08 14:28:05

+0

谢谢,它肯定适用于5.0和5.1,我很担心4.3 – Mona 2012-04-10 09:11:20

2
//import fremework in .h file 

#import <AVFoundation/AVFoundation.h> 
{ 
AVCaptureSession *torchSession; 
} 

@property(nonatomic,retain)AVCaptureSession *torchSession; 


-(IBAction)onoff:(id)sender; 

//implement in .m file 

@synthesize torchSession; 

-(IBAction)onoff:(id)sender 
{ 
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    if ([device hasTorch] && [device hasFlash]) 
    { 
     if (device.torchMode == AVCaptureTorchModeOff) 
     { 
      [button setTitle:@"OFF" forState:UIControlStateNormal]; 

      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]; 
      [session release]; 
     } 
     else 
     { 
      [button setTitle:@"ON" forState:UIControlStateNormal]; 
      [torchSession stopRunning]; 
     } 
    } 
} 

- (void)dealloc 
{ 
    [torchSession release]; 
    [super dealloc]; 
} 
2

我写了一个火炬插件,用于科尔多瓦2.2.0适用。你可以在这里找到它:

​​

2

从的iOS 6.0及以上版本,在切换火炬闪光灯开/关,

- (void) toggleFlash { 
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    if ([device hasTorch] && [device hasFlash]){ 
     [device lockForConfiguration:nil]; 
     [device setFlashMode:(device.flashActive) ? AVCaptureFlashModeOff : AVCaptureFlashModeOn]; 
     [device setTorchMode:(device.torchActive) ? AVCaptureTorchModeOff : AVCaptureTorchModeOn]; 
     [device unlockForConfiguration]; 
    } 
} 

附:如果您没有开/关功能,这种方法只能被暗示。请记住还有一个选项Auto。即AVCaptureFlashModeAutoAVCaptureTorchModeAuto。为了支持自动模式,您还可以跟踪当前模式并根据闪光灯的变化模式。

1

这项工作很好..希望它可以帮助某人!

-(IBAction)flashlight:(id)sender { 

    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    if ([device hasTorch] && [device hasFlash]){ 

     if (device.torchMode == AVCaptureTorchModeOff) { 

      [sender setTitle:@"Torch Off" forState:UIControlStateNormal]; 

      AVCaptureDeviceInput *flashInput = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil]; 
      AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init]; 

      AVCaptureSession *cam = [[AVCaptureSession alloc] init]; 

      [cam beginConfiguration]; 
      [device lockForConfiguration:nil]; 

      [device setTorchMode:AVCaptureTorchModeOn]; 
      [device setFlashMode:AVCaptureFlashModeOn]; 

      [cam addInput:flashInput]; 
      [cam addOutput:output]; 

      [device unlockForConfiguration]; 

      [cam commitConfiguration]; 
      [cam startRunning]; 

      [self setTorchSession:cam]; 
     } 
     else { 
      [sender setTitle:@"Torch On" forState:UIControlStateNormal]; 
      [_torchSession stopRunning]; 
     } 
    } 
} 
2

雨燕2.0的版本:

func setTorchLevel(torchLevel: Float) 
{ 
    self.captureSession?.beginConfiguration() 
    defer { 
     self.captureSession?.commitConfiguration() 
    } 

    if let device = backCamera?.device where device.hasTorch && device.torchAvailable { 
     do { 
      try device.lockForConfiguration() 
      defer { 
       device.unlockForConfiguration() 
      } 

      if torchLevel <= 0.0 { 
       device.torchMode = .Off 
      } 
      else if torchLevel >= 1.0 { 
       try device.setTorchModeOnWithLevel(min(torchLevel, AVCaptureMaxAvailableTorchLevel)) 
      } 
     } 
     catch let error { 
      print("Failed to set up torch level with error \(error)") 
      return 
     } 
    } 
}