2010-07-06 13 views
44

So che l'unico modo per accendere il flash e tenerlo acceso su iPhone 4 è accendere la videocamera. Comunque non sono sicuro del codice. Ecco cosa sto cercando:Accensione torcia/flash su 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; 
    } 
} 

Qualcuno sa se questo funzionerebbe o mi manca qualcosa? (Non ho ancora un iPhone 4 da testare - solo per provare alcune delle nuove API).

Grazie

risposta

15

il lockforConfiguration è impostato nel codice, in cui si dichiara la AVCaptureDevice è una struttura.

[videoCaptureDevice lockForConfiguration:nil]; 
18

Vedere una risposta migliore di seguito:https://stackoverflow.com/a/10054088/308315


Vecchia risposta:

In primo luogo, nel AppDelegate .h del file:

#import <AVFoundation/AVFoundation.h> 

@interface AppDelegate : NSObject <UIApplicationDelegate> { 

    AVCaptureSession *torchSession; 

} 

@property (nonatomic, retain) AVCaptureSession * torchSession; 

@end 

Poi, nel il tuo AppDe Legato di file .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; 
} 

Poi ogni volta che si desidera attivarla, basta fare qualcosa di simile:

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

} 

E simile per spegnerlo:

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

Nel file appdelegate.m, si dovrebbe racchiudere il contenuto del 'del metodo di init' con qualcosa come:' if ((self = [super init])) {...} return self; ' – Senseful

+0

Questo è troppo contrastante e mantenere la sessione consuma batteria. Prova il seguente metodo di Tibidabo – doozMen

69

Ecco un versione più breve che ora puoi utilizzare per accendere o spegnere la luce:

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

UPDATE: (Marzo 2015)

Con iOS 6.0 e versioni successive, è possibile controllare la luminosità o il livello della torcia utilizzando il seguente metodo:

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

Si consiglia inoltre di monitorare il valore di ritorno (success) da setTorchModeOnWithLevel:. Si può avere un guasto se si tenta di impostare il livello troppo alto e la torcia si sta surriscaldando. In tal caso, impostando il livello su AVCaptureMaxAvailableTorchLevel, il livello verrà impostato sul livello più alto consentito in base alla temperatura della torcia.

+2

Ciò ha reso le cose più semplici e più reattive nei miei tentativi di attivare il flash. Avevo usato il metodo che iWasRobbed ha pubblicato, ma non era molto reattivo. –

+0

bellezza! ha funzionato un fascino. –

35

La risposta di iWasRobbed è ottima, tranne che c'è uno AVCaptureSession in esecuzione in background tutto il tempo. Sul mio iPhone 4s lo occupa circa il 12% di potenza della CPU in base allo Strumento, quindi la mia app ha impiegato circa l'1% di batteria in un minuto. In altre parole, se il dispositivo è pronto per l'acquisizione AV non è economico.

Utilizzando il codice qui sotto la mia app richiede lo 0,187% al minuto, quindi la durata della batteria è più di 5 volte più lunga.

Questo codice funziona perfettamente su qualsiasi dispositivo (testato su 3GS (senza flash) e 4s). Testato su 4.3 anche nel simulatore.

#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

Per quali versioni di ios funziona? – Mona

+1

dovrebbe funzionare su tutti i, cioè dovrebbe funzionare da 5.0 e non dovrebbe bloccarsi al di sotto di quello. – Tibidabo

+0

grazie, sicuramente funziona su 5.0 e 5.1, sono preoccupato per 4.3 – Mona

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

da iOS 6.0 e versioni successive, commutando la torcia flash on/off,

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

P.S. Questo approccio è suggeribile solo se non si dispone di una funzione on/off. Ricorda che c'è un'altra opzione Auto. Ad esempio AVCaptureFlashModeAuto e AVCaptureTorchModeAuto. Per supportare anche la modalità automatica, hai tenuto traccia della modalità corrente e in base a quella modalità di modifica della torcia flash &.

1

Questo lavoro è molto buono .. spero che aiuti qualcuno!

-(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

Swift 2.0 Versione:

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 
     } 
    } 
}