现在我试图允许用户在我的应用程序中拍照而不使用UIImagePickerController。我正在使用AVCaptureSession和所有相关的类来加载相机提要作为我在其中一个视图控制器上的全屏视图的子图层。代码可以工作,但遗憾的是相机加载速度很慢。通常需要2-3秒。这是我的代码:
session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetMedium;
if ([session canSetSessionPreset:AVCaptureSessionPresetHigh])
//Check size based configs are supported before setting them
[session setSessionPreset:AVCaptureSessionPresetHigh];
[session setSessionPreset:AVCaptureSessionPreset1280x720];
CALayer *viewLayer = self.liveCameraFeed.layer;
//NSLog(@"viewLayer = %@", viewLayer);
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = viewLayer.bounds;
[viewLayer addSublayer:captureVideoPreviewLayer];
AVCaptureDevice *device;
if(isFront)
{
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
else
{
device = [self frontCamera];
}
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput * audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
[session addInput:audioInput];
NSError *error = nil;
input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
//NSLog(@"ERROR: trying to open camera: %@", error);
}
[session addInput:input];
[session startRunning];
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[session addOutput:stillImageOutput];
有没有办法加快速度?我已经尝试使用Grand Central Dispatch和NSThread在另一个线程上加载它,虽然这使得应用程序冻结它使得相机的加载时间更长。任何帮助表示赞赏。
在我的情况下,我需要等待session
开始运行
dispatch_async(queue) {
self.session.startRunning()
dispatch_async(dispatch_get_main_queue()) {
self.delegate?.cameraManDidStart(self)
let layer = AVCaptureVideoPreviewLayer(session: self.session)
}
}
您可以在viewWillAppear
时加载AVCaptureSession。这个对我有用。当我从其他视图切换到AVCaptureSession
视图时,我看到相机立即运行。
等待AVCaptureSession的startRunning
功能也是我的解决方案。您可以在全局异步中运行startRunning
,然后在主线程中添加AVCaptureVideoPreviewLayer。
Swift 4样本
DispatchQueue.global().async {
self.captureSession.startRunning()
DispatchQueue.main.async {
let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
}
}
对于任何感兴趣的人,我想出的解决方案是在不同的线程上预装相机并保持打开状态。
我尝试了上述所有方法,但它不如Instagram或Facebook那么好,所以我在父屏幕中加载AVCaptureDevice,AVCaptureVideoPreviewLayer,AVCaptureSession并将其作为参数传递给子屏幕。它加载速度非常快。