web-dev-qa-db-fra.com

Allumez la torche / le flash sur iPhone

Je sais que la seule façon d'activer le flash et de le garder sur l'iPhone 4 est d'allumer la caméra vidéo. Je ne suis pas trop sûr du code. Voici ce que j'essaye:

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

Est-ce que quelqu'un sait si cela fonctionnerait ou est-ce que je manque quelque chose? (Je n'ai pas encore d'iPhone 4 à tester - j'essaye juste certaines des nouvelles API).

Merci

44
John

le lockforConfiguration est défini dans votre code, où vous déclarez que votre AVCaptureDevice est une propriété.

[videoCaptureDevice lockForConfiguration:nil];
15
Gustavo Barrientos

Voici une version plus courte que vous pouvez maintenant utiliser pour allumer ou éteindre la lumière:

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

MISE À JOUR: (mars 2015)

Avec iOS 6.0 et versions ultérieures, vous pouvez contrôler la luminosité ou le niveau de la torche en utilisant la méthode suivante:

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

Vous pouvez également vouloir surveiller la valeur de retour (success) à partir de setTorchModeOnWithLevel:. Vous pouvez obtenir un échec si vous essayez de régler le niveau trop haut et que la torche surchauffe. Dans ce cas, régler le niveau sur AVCaptureMaxAvailableTorchLevel mettra le niveau au niveau le plus élevé autorisé compte tenu de la température de la torche.

71
mahboudz

la réponse d'iWasRobbed est excellente, sauf qu'il y a un AVCaptureSession fonctionnant en arrière-plan tout le temps. Sur mon iPhone 4, cela nécessite environ 12% de puissance CP selon Instrument, mon application a donc pris environ 1% de batterie en une minute. En d'autres termes, si l'appareil est prêt pour la capture AV, ce n'est pas bon marché.

L'utilisation du code ci-dessous mon application nécessite 0,187% par minute, donc la durée de vie de la batterie est plus de 5 fois plus longue.

Ce code fonctionne très bien sur n'importe quel appareil (testé à la fois sur 3GS (pas de flash) et sur 4s). Testé sur 4.3 dans le simulateur également.

#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];
        }
    }
}
36
Tibidabo

Voir une meilleure réponse ci-dessous: https://stackoverflow.com/a/10054088/308315


Ancienne réponse:

Tout d'abord, dans votre fichier .h AppDelegate:

#import <AVFoundation/AVFoundation.h>

@interface AppDelegate : NSObject <UIApplicationDelegate> {

    AVCaptureSession *torchSession;

}

@property (nonatomic, retain) AVCaptureSession * torchSession;

@end

Ensuite, dans votre fichier AppDelegate .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;
}

Ensuite, chaque fois que vous souhaitez l'activer, faites simplement quelque chose comme ceci:

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

}

Et similaire pour le désactiver:

// 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];
}
18
iwasrobbed

À partir d'iOS 6.0 et supérieur, activer/désactiver le flash de la torche,

- (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. Cette approche n'est suggérable que si vous n'avez pas de fonction marche/arrêt. N'oubliez pas qu'il existe une autre option Auto. c'est-à-dire AVCaptureFlashModeAuto et AVCaptureTorchModeAuto. Pour prendre également en charge le mode automatique, vous avez suivi le mode actuel et basé sur ce mode de changement de flash et de torche.

2
Hemang
//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
Rushabh

Version Swift 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
        }
    }
}
2
Avt

Ce travail est très bien .. j'espère qu'il aidera quelqu'un!

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