xcode iOS AVCaptureVideoPreviewLayer 未显示在 UIView 中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15533264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS AVCaptureVideoPreviewLayer not showing in UIView?
提问by Corey
The Problem
问题
I have a sample application from Apple (SquareCam)that I'm using as reference to create a custom interface for a camera. I'm using the AVFoundation framework. If I build and run the project from Apple, the app runs as expected. However, if I take the same code from that project and place it in a new project in Xcode, the video preview will not display.
我有一个来自 Apple (SquareCam)的示例应用程序,我将其用作创建相机自定义界面的参考。我正在使用 AVFoundation 框架。如果我从 Apple 构建并运行该项目,该应用程序将按预期运行。但是,如果我从该项目中获取相同的代码并将其放入 Xcode 中的新项目中,则不会显示视频预览。
I have simplified the code down to the essential components to run a video preview layer. Again, this code runs fine as is in the Apple (SquareCam) project, but does not display in my new project.
我已将代码简化为运行视频预览层的基本组件。同样,此代码在 Apple (SquareCam) 项目中运行良好,但未显示在我的新项目中。
The Code
编码
- (void)setupAVCapture {
NSError *error = nil;
AVCaptureSession *session = [AVCaptureSession new];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
[session setSessionPreset:AVCaptureSessionPreset640x480];
else
[session setSessionPreset:AVCaptureSessionPresetPhoto];
// Select a video device, make an input
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if ([session canAddInput:deviceInput])
[session addInput:deviceInput];
previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[previewLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
CALayer *rootLayer = [previewView layer];
[rootLayer setMasksToBounds:YES];
[previewLayer setFrame:[rootLayer bounds]];
[rootLayer addSublayer:previewLayer];
[session startRunning];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupAVCapture];
}
What Have I Tried?
我尝试了什么?
I have all of the outlets set up correctly. I have all of the framework libraries in my build phase. Both projects are using storyboard. What's odd is that I am able to capture an image from the camera and even switch the source from front to back. But the preview will not display. The Apple project was not setup with ARC. So, I updated the project to use ARC. Again, runs great in the Apple project, but not in a new project.
我已正确设置所有插座。我在构建阶段拥有所有框架库。这两个项目都使用故事板。奇怪的是,我能够从相机捕获图像,甚至可以从前向后切换源。但是预览不会显示。Apple 项目未使用 ARC 设置。因此,我更新了项目以使用 ARC。同样,在 Apple 项目中运行良好,但在新项目中则不然。
Thoughts?
想法?
Any ideas on what the issue could be? Is there a project setting that could cause this?
关于问题可能是什么的任何想法?是否有可能导致这种情况的项目设置?
回答by Brenden
Had the same issue and the key was setting the AVCaptureVideoPreviewLayer
's frame to the bounds of the UIView:
有同样的问题,关键是将AVCaptureVideoPreviewLayer
的框架设置为 UIView 的边界:
// Setup camera preview image
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];
previewLayer.frame = _cameraPreview.bounds;
[_cameraPreview.layer addSublayer:previewLayer];
回答by Aki
I had a similar issue in my project. From your code excerpt, it is hard to tell who is invoking setupAVCapture method. In my case, I had to ensure that AVCaptureVideoPreviewLayer is created on the main thread.
我在我的项目中遇到了类似的问题。从您的代码摘录中,很难判断谁在调用 setupAVCapture 方法。就我而言,我必须确保在主线程上创建 AVCaptureVideoPreviewLayer。
There are couple of options. You can invoke setupAVCapture on the main application thread by wrapping the call in the following block:
有几个选项。您可以通过将调用包装在以下块中来在主应用程序线程上调用 setupAVCapture:
dispatch_async(dispatch_get_main_queue(), ^{
// call setupAVCapture() method in here
});
If that is not an option, you can only do that on the following part of your code:
如果这不是一个选项,您只能在代码的以下部分执行此操作:
dispatch_async(dispatch_get_main_queue(), ^{
previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[previewLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
CALayer *rootLayer = [previewView layer];
[rootLayer setMasksToBounds:YES];
[previewLayer setFrame:[rootLayer bounds]];
[rootLayer addSublayer:previewLayer];
});