AVFoundation 中关于视频主要的类
捕捉预览除了用AVCaptureVideoPreviewLayer外,还可以用OpenGL ES绘制,我们可以从输出数据流捕捉单一的图像帧,并使用 OpenGL ES手动地把它们显示在 view 上。如果我们想对预览视图进行操作,如使用滤镜,我们就必须这样做。这里不做深入研究,下面给出一段简单的实现代码: // 创建glview EAGLContext *context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2]; GLKView *glView = [[GLKView alloc]initWithFrame:self.view.bounds context:context]; [EAGLContext setCurrentContext:context]; [self.view addSubview:glView]; glView.transform = CGAffineTransformMakeRotation(M_PI_2); glView.frame = [UIApplication sharedApplication].keyWindow.bounds; // 在视频输出函数中绘制出来 -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{ if (_glview.context != [EAGLContext currentContext]) { [EAGLContext setCurrentContext:_glview.context]; } CVImageBufferRef imageRef = CMSampleBufferGetImageBuffer(sampleBuffer); CIImage *image = [CIImage imageWithCVImageBuffer:imageRef]; [_glview bindDrawable]; [_cicontext drawImage:image inRect:image.extent fromRect:image.extent]; [_glview display]; }
- (BOOL)switchCameras{ NSError *error; AVCaptureDevice *videoDevice = [self inactiveCamera]; AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; if (videoInput) { AVCaptureFlashMode flashMode = [self flashMode]; // 转换摄像头 [_session beginConfiguration]; [_session removeInput:_deviceInput]; if ([_session canAddInput:videoInput]) { CATransition *animation = [CATransition animation]; animation.type = @"oglFlip"; animation.subtype = kCATransitionFromLeft; animation.duration = 0.5; [self.cameraView.previewView.layer addAnimation:animation forKey:@"flip"]; [_session addInput:videoInput]; _deviceInput = videoInput; } else { [_session addInput:_deviceInput]; } [_session commitConfiguration]; // 完成后需要重新设置视频输出链接 _videoConnection = [_videoOutput connectionWithMediaType:AVMediaTypeVideo]; // 如果后置转前置,系统会自动关闭手电筒,如果之前打开的,需要更新UI if (videoDevice.position == AVCaptureDevicePositionFront) { [self.cameraView changeTorch:NO]; } // 前后摄像头的闪光灯不是同步的,所以在转换摄像头后需要重新设置闪光灯 [self changeFlash:flashMode]; return nil; } return error; }
AVCaptureDevice *device = [self activeCamera]; if (device.torchMode != torchMode && [device isTorchModeSupported:torchMode]) { NSError *error; if ([device lockForConfiguration:&error]) { device.torchMode = torchMode; [device unlockForConfiguration]; } else{ [self showError:error]; } }
AVCaptureDevice *device = [self activeCamera]; if (device.flashMode != flashMode && [device isFlashModeSupported:flashMode]) { NSError *error; if ([device lockForConfiguration:&error]) { device.flashMode = flashMode; [device unlockForConfiguration]; } else{ [self showError:error]; } }
- (void)focusAtPoint:(CGPoint)point { AVCaptureDevice *device = [self activeCamera]; if ([self cameraSupportsTapToFocus] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) { NSError *error; if ([device lockForConfiguration:&error]) { device.focusPointOfInterest = point; device.focusMode = AVCaptureFocusModeAutoFocus; [device unlockForConfiguration]; } else{ [self showError:error]; } } }
static const NSString *CameraAdjustingExposureContext; - (void)exposeAtPoint:(CGPoint)point{ AVCaptureDevice *device = [self activeCamera]; if ([self cameraSupportsTapToExpose] && [device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) { NSError *error; if ([device lockForConfiguration:&error]) { device.exposurePointOfInterest = point; device.exposureMode = AVCaptureExposureModeContinuousAutoExposure; if ([device isExposureModeSupported:AVCaptureExposureModeLocked]) { [device addObserver:self forKeyPath:@"adjustingExposure" options:NSKeyValueObservingOptionNew context:&CameraAdjustingExposureContext]; } [device unlockForConfiguration]; } else{ [self showError:error]; } } } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == &CameraAdjustingExposureContext) { AVCaptureDevice *device = (AVCaptureDevice *)object; if (!device.isAdjustingExposure && [device isExposureModeSupported:AVCaptureExposureModeLocked]) { [object removeObserver:self forKeyPath:@"adjustingExposure" context:&CameraAdjustingExposureContext]; dispatch_async(dispatch_get_main_queue(), ^{ NSError *error; if ([device lockForConfiguration:&error]) { device.exposureMode = AVCaptureExposureModeLocked; [device unlockForConfiguration]; } else{ [self showError:error]; } }); } } else{ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } }
- (BOOL)resetFocusAndExposureModes{ AVCaptureDevice *device = [self activeCamera]; AVCaptureExposureMode exposureMode = AVCaptureExposureModeContinuousAutoExposure; AVCaptureFocusMode focusMode = AVCaptureFocusModeContinuousAutoFocus; BOOL canResetFocus = [device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode]; BOOL canResetExposure = [device isExposurePointOfInterestSupported] && [device isExposureModeSupported:exposureMode]; CGPoint centerPoint = CGPointMake(0.5f, 0.5f); NSError *error; if ([device lockForConfiguration:&error]) { if (canResetFocus) { device.focusMode = focusMode; device.focusPointOfInterest = centerPoint; } if (canResetExposure) { device.exposureMode = exposureMode; device.exposurePointOfInterest = centerPoint; } [device unlockForConfiguration]; return YES; } else{ [self showError:error]; return NO; } }
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有