【问题标题】:AVCaptureVideoPreviewLayer: using with Storyboard and AutolayoutAVCaptureVideoPreviewLayer:与 Storyboard 和 Autolayout 一起使用
【发布时间】:2015-01-21 09:36:42
【问题描述】:

我的故事板上有一个UIView,有四个简单的约束设置填充整个屏幕 - 我的应用程序仅用于横向使用。此UIView 用于显示相机的实时预览,使用AVCaptureVideoPreviewLayer

我尝试使用在 StackOverflow 和更广泛的互联网上找到的一些代码示例,启动 AVCaptureSessionAVCaptureVideoPreviewLayer;但是,没有一个成功运行。故事板上的UIView 总是无法在屏幕上显示(视图加载时出现白屏)

我希望通过使用约束的界面构建器创建我的应用的整个界面,同时获得AVCaptureVideoPreviewLayer 的功能。如果他们有可能的解决方案,有人可以提供完整的代码示例来帮助我吗?

【问题讨论】:

  • 为什么投反对票?有什么我可以更好地解释的吗?

标签: ios objective-c uiview avfoundation avcapturesession


【解决方案1】:

这是我的代码,它适用于我。头文件AVCameraCaptureData.h:

@interface AVCameraCaptureData : NSObject

@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureConnection *captureConnection;
@property (nonatomic, strong) AVCaptureDeviceInput *deviceInput;
@property (nonatomic, strong) AVCaptureStillImageOutput *captureOutput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;

@end

#if defined(__cplusplus)
extern "C"
{
 #endif /* defined(__cplusplus) */

AVCaptureDevice* getCaptureDeviceByPosition(AVCaptureDevicePosition position);
AVCaptureStillImageOutput* getCaptureOutput();
AVCaptureConnection* ConnectionWithMediaType (NSString* mediaType, NSArray* fromConnections);
AVCaptureVideoPreviewLayer* getCapturePreviewLayer(AVCaptureSession* captureSession);
AVCameraCaptureData* CreateCaptureData (AVCaptureDevicePosition position, CGRect presentLayerFrame, NSString* sessionPreset);
#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */

AVCameraCaptureData.m 文件:

#import "AVCameraCaptureData.h"
#import "AVCameraUtil.h"

@implementation AVCameraCaptureData

AVCaptureDevice* getCaptureDeviceByPosition(AVCaptureDevicePosition position)
{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices)
{
    if ([device position] == position)
        return device;
}

return nil;
}

AVCaptureStillImageOutput* getCaptureOutput()
{
AVCaptureStillImageOutput* captureOutput = [[AVCaptureStillImageOutput alloc] init];

NSDictionary* outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[captureOutput setOutputSettings:outputSettings];

return captureOutput;
}

AVCaptureConnection* ConnectionWithMediaType (NSString* mediaType, NSArray* fromConnections)
{
for (AVCaptureConnection* connection in fromConnections)
{
    for (AVCaptureInputPort* port in [connection inputPorts])
    {
        if ([[port mediaType] isEqual:mediaType])
            return connection;
    }
}
return nil;
}

AVCaptureVideoPreviewLayer* getCapturePreviewLayer(AVCaptureSession* captureSession)
{
AVCaptureVideoPreviewLayer* previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
//please set frame for yourself
[previewLayer setFrame:[AVCameraUtil screenBoundsFixedToPortraitOrientation]];
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

return previewLayer;
}

AVCameraCaptureData* CreateCaptureData (AVCaptureDevicePosition position, CGRect presentLayerFrame, NSString* sessionPreset)
{
AVCaptureSession* captureSession = [[AVCaptureSession alloc] init];

if (sessionPreset == nil)
    [captureSession setSessionPreset:AVCaptureSessionPresetPhoto];
else
    [captureSession setSessionPreset:sessionPreset];

AVCaptureDevice *device = getCaptureDeviceByPosition (position);
AVCaptureDeviceInput *videoDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:nil];

if ([captureSession canAddInput:videoDeviceInput])
    [captureSession addInput:videoDeviceInput];

AVCaptureStillImageOutput* captureOutput = getCaptureOutput();

if ([captureSession canAddOutput:captureOutput])
    [captureSession addOutput:captureOutput];

AVCameraCaptureData *data = [[AVCameraCaptureData alloc] init];
data.captureSession = captureSession;
data.deviceInput = videoDeviceInput;
data.captureOutput = captureOutput;
data.captureConnection = ConnectionWithMediaType(AVMediaTypeVideo, [captureOutput connections]);
data.previewLayer = getCapturePreviewLayer(captureSession);

return data;
}

@end

然后你可以在你的控制器中使用函数来初始化 AVCameraCaptureData

CreateCaptureData(AVCaptureDevicePositionBack, self.view.frame,nil);

开始运行会话:

[self.captureData.captureSession startRunning];

将 AVCaptureVideoPreviewLayer 添加到 view.layer:

[self.view.layer addSublayer:self.captureData.previewLayer];

【讨论】:

  • 我应该用什么替换AVCameraUtil
  • 此外,即使在导入AVCameraCaptureData 文件后,也会出现错误Property 'captureData' not found on object of type 'ViewController'
  • "captureData" 是您的 ViewController 的 @property。
猜你喜欢
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2014-12-25
  • 2012-11-30
  • 2021-04-01
  • 2018-09-05
  • 2013-05-12
相关资源
最近更新 更多