مشاكل مع AVCaptureSession في الوضع الأفقي على iPad
-
27-12-2019 - |
سؤال
لقد كنت أحاول التقاط الإطارات من الكاميرا الأمامية وعرضها على العرض.هنا هو الكود الخاص بي
_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
, ، ولكن للأسف دون جدوى.
المحلول
تم حلها، والآن تعمل في جميع الاتجاهات.نحن بحاجة إلى تعيين هذا
_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];
نصائح أخرى
في سويفت 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)
}
لا تنتمي إلى StackOverflow