11

问题

我有一个来自 Apple (SquareCam) 的示例应用程序,我将其用作为相机创建自定义界面的参考。我正在使用 AVFoundation 框架。如果我从 Apple 构建并运行该项目,该应用程序将按预期运行。但是,如果我从该项目中获取相同的代码并将其放在 Xcode 中的新项目中,则不会显示视频预览。

我已将代码简化为运行视频预览层的基本组件。同样,此代码在 Apple (SquareCam) 项目中运行良好,但未显示在我的新项目中。

编码

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

我尝试了什么?

我已正确设置所有网点。我在构建阶段拥有所有框架库。这两个项目都使用故事板。奇怪的是,我能够从相机捕捉图像,甚至可以将源从前切换到后。但不会显示预览。Apple 项目未使用 ARC 设置。所以,我更新了项目以使用 ARC。同样,在 Apple 项目中运行良好,但在新项目中却没有。

想法?

关于问题可能是什么的任何想法?是否有可能导致这种情况的项目设置?

4

3 回答 3

27

有同样的问题,关键是将AVCaptureVideoPreviewLayer' 框架设置为 UIView 的边界:

// Setup camera preview image
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];
previewLayer.frame = _cameraPreview.bounds;
[_cameraPreview.layer addSublayer:previewLayer];
于 2013-09-25T21:39:01.410 回答
6

我的项目中有类似的问题。从您的代码摘录中,很难判断谁在调用 setupAVCapture 方法。就我而言,我必须确保在主线程上创建 AVCaptureVideoPreviewLayer。

有几个选项。您可以通过将调用包装在以下块中来在主应用程序线程上调用 setupAVCapture:

dispatch_async(dispatch_get_main_queue(), ^{
   // call setupAVCapture() method in here
});

如果这不是一个选项,您只能在代码的以下部分执行此操作:

  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];
   });
于 2013-03-20T21:39:23.553 回答
0

在主线程上设置框架非常重要。

斯威夫特 5

let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = .resizeAspectFill
layer.addSublayer(previewLayer)
DispatchQueue.main.async {
  previewLayer.frame = self.bounds
}
于 2021-08-04T11:29:55.993 回答