簡體   English   中英

AVCaptureVideoPreviewLayer:與情節提要和自動布局一起使用

[英]AVCaptureVideoPreviewLayer: using with Storyboard and Autolayout

我在Storyboard上有一個UIView ,它具有四個簡單的約束,可將整個屏幕設置為填充-我的應用程序僅用於橫向使用。 UIView使用AVCaptureVideoPreviewLayer來顯示攝像機的實時預覽。

我嘗試使用在StackOverflow和更廣泛的Internet上找到的一些代碼示例,來初始化AVCaptureSessionAVCaptureVideoPreviewLayer 但是,沒有一個成功運行。 故事板上的UIView總是最終無法在屏幕上顯示(視圖加載時為白屏)

我希望使用約束使用接口構建器創建應用程序的整個接口,並獲得AVCaptureVideoPreviewLayer的功能。 如果有可能的解決方案,有人可以提供完整的代碼示例來幫助我嗎?

這是我的代碼,對我有用。 頭文件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];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM