2014-06-05 14 views
12

Próbowałem przechwytywać ramki z przedniej kamery i prezentować ją w widoku. Oto mój kodProblemy z AVCaptureSession w trybie poziomym na iPadzie

_session = [[AVCaptureSession alloc] init]; 
_session.sessionPreset = AVCaptureSessionPreset640x480; 

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
NSError *error = nil; 
AVCaptureDeviceInput *deviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error]; 

if (deviceInput) { 
    [_session addInput:deviceInput]; 
} 
else { 
    DDLogInfo(@"Some wierd shit happened"); 
    return; 
} 

// Session output 
/* 
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; 
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; 
[_session addOutput:output]; 
output.metadataObjectTypes = @[AVMetadataObjectTypeFace]; 
AVCaptureConnection *connection = [output connectionWithMediaType:AVMediaTypeMetadata]; 
connection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft; 
*/ 

// Session output 
AVCaptureMovieFileOutput *videoOutput = [[AVCaptureMovieFileOutput alloc] init]; 
[_session addOutput:videoOutput]; 
AVCaptureConnection *connection = [videoOutput connectionWithMediaType:AVMediaTypeVideo]; 
connection.videoOrientation = AVCaptureVideoOrientationPortrait; 

// Preview layer 
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session]; 
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
_previewLayer.frame = CGRectMake(0, 0, self.middleView.frame.size.width, self.middleView.frame.size.height); 
[self.middleView.layer addSublayer:_previewLayer]; 

[_session startRunning]; 

Problemem jest to, kiedy mój iPad jest krajobraz, obraz na warstwie prezentacji są obrócone o 90 stopni. Jak to naprawić? Przeglądam przepełnienie stosu, próbując coś zrobić z AVCaptureConnection, ale niestety bez skutku.

Odpowiedz

22

Rozwiązał to, teraz działa we wszystkich orientacjach. Musimy ustawić

_previewLayer.connection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation]; 

gdzie metoda jest:

- (AVCaptureVideoOrientation) videoOrientationFromCurrentDeviceOrientation { 
switch (self.interfaceOrientation) { 
    case UIInterfaceOrientationPortrait: { 
     return AVCaptureVideoOrientationPortrait; 
    } 
    case UIInterfaceOrientationLandscapeLeft: { 
     return AVCaptureVideoOrientationLandscapeLeft; 
    } 
    case UIInterfaceOrientationLandscapeRight: { 
     return AVCaptureVideoOrientationLandscapeRight; 
    } 
    case UIInterfaceOrientationPortraitUpsideDown: { 
     return AVCaptureVideoOrientationPortraitUpsideDown; 
    } 
} 
} 

także na wyjściu przechwytywania musimy ustawić:

AVCaptureConnection *output2VideoConnection = [videoOutput connectionWithMediaType:AVMediaTypeVideo]; 
output2VideoConnection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation]; 
+0

nie zapomnę cię trzeba ponownie ustawić '.connection.videoOrientation', gdy użytkownik obraca swoje urządzenie :) – Arefly

6

W Swift 3:

Najpierw musimy ustawić previewLayer.connection.videoOrientation jak MegaManX do

previewLayer.connection.videoOrientation = self.videoOrientationFromCurrentDeviceOrientation() 

gdzie metoda jest:

func videoOrientationFromCurrentDeviceOrientation() -> AVCaptureVideoOrientation { 
    switch UIApplication.shared.statusBarOrientation { 
    case .portrait: 
     return AVCaptureVideoOrientation.portrait 
    case .landscapeLeft: 
     return AVCaptureVideoOrientation.landscapeLeft 
    case .landscapeRight: 
     return AVCaptureVideoOrientation.landscapeRight 
    case .portraitUpsideDown: 
     return AVCaptureVideoOrientation.portraitUpsideDown 
    default: 
     // Can this happen? 
     return AVCaptureVideoOrientation.portrait 
    } 
} 

Następnie mamy również obsługiwać videoOrientation gdy użytkownik obraca urządzenie (metody pochodzą z here)

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 

    coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) -> Void in 
     self.previewLayer.connection.videoOrientation = self.videoOrientationFromCurrentDeviceOrientation() 

     }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in 
      // Finish Rotation 
    }) 

    super.viewWillTransition(to: size, with: coordinator) 
} 
+0

Co zrobić, gdy orientacja urządzenia jest zablokowana? Metoda 'viewWillTransitionToSize' nie wywoła. Jak sobie z tym poradzić. Muszę wykryć orientację obrazu, gdy urządzenie jest zablokowane. –

+0

@mahbaleshwarhegde masz na myśli, mimo że orientacja urządzenia jest zablokowana, nadal chcesz, aby obraz obracał się wraz z urządzeniem? – Arefly

+0

tak. gdy urządzenie jest zablokowane otrzymuję statusBarOrientation jest portretem. Dlatego połączenie wideo staje się portretem, mimo że zrobiłem zdjęcie w trybie poziomym. Jak zrobić. dowolny pomysł? –

Powiązane problemy