AVCaptureVideoPreviewLayer:与Storyboard和Autolayout一起使用

时间:2015-01-21 09:36:42

标签: ios objective-c uiview avfoundation avcapturesession

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

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

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

1 个答案:

答案 0 :(得分:0)

这是我的代码,它对我有用。头文件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];