2010-07-06 121 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 
     } 
    } 
}