我一直试图从前置摄像头捕捉帧并将其呈现在视图上.这是我的代码
_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];
问题是,当我的iPad是风景时,表现层上的图像旋转90度.我该如何解决?我一直在浏览堆栈溢出,试图做一些事情AVCaptureConnection
,但唉无济于事.
在Swift 3中:
首先,我们必须previewLayer.connection.videoOrientation
像MegaManX那样设置
previewLayer.connection.videoOrientation = self.videoOrientationFromCurrentDeviceOrientation()
方法是:
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 } }
然后我们还必须处理videoOrientation
用户旋转设备的时间(方法来自这里)
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) }
解决了它,现在它正在各个方向工作.我们需要设置它
_previewLayer.connection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation];
方法是:
- (AVCaptureVideoOrientation) videoOrientationFromCurrentDeviceOrientation { switch (self.interfaceOrientation) { case UIInterfaceOrientationPortrait: { return AVCaptureVideoOrientationPortrait; } case UIInterfaceOrientationLandscapeLeft: { return AVCaptureVideoOrientationLandscapeLeft; } case UIInterfaceOrientationLandscapeRight: { return AVCaptureVideoOrientationLandscapeRight; } case UIInterfaceOrientationPortraitUpsideDown: { return AVCaptureVideoOrientationPortraitUpsideDown; } } }
同样在捕获输出上我们需要设置:
AVCaptureConnection *output2VideoConnection = [videoOutput connectionWithMediaType:AVMediaTypeVideo]; output2VideoConnection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation];