【移动应用开发技术】怎么在iOS中使用AVCaptureSession实现视频录制功能_第1页
【移动应用开发技术】怎么在iOS中使用AVCaptureSession实现视频录制功能_第2页
【移动应用开发技术】怎么在iOS中使用AVCaptureSession实现视频录制功能_第3页
【移动应用开发技术】怎么在iOS中使用AVCaptureSession实现视频录制功能_第4页
【移动应用开发技术】怎么在iOS中使用AVCaptureSession实现视频录制功能_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】怎么在iOS中使用AVCaptureSession实现视频录制功能

本篇文章给大家分享的是有关怎么在iOS中使用AVCaptureSession实现视频录制功能,在下觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着在下一起来看看吧。具体内容如下#import

"RecordingVideoViewController.h"

#import

<AVFoundation/AVFoundation.h>

#import

<AssetsLibrary/AssetsLibrary.h>

@interface

RecordingVideoViewController

()<AVCaptureFileOutputRecordingDelegate>

//会话

负责输入和输出设备之间的数据传递

@property

(strong,nonatomic)

AVCaptureSession

*captureSession;

//设备输入

负责从AVCaptureDevice获得输入数据

@property

(strong,nonatomic)

AVCaptureDeviceInput

*videoCaptureDeviceInput;

@property

(strong,nonatomic)

AVCaptureDeviceInput

*audioCaptureDeviceInput;

//视频输出流

@property

(strong,nonatomic)

AVCaptureMovieFileOutput

*captureMovieFileOutput;

//相机拍摄预览图层

@property

(strong,nonatomic)

AVCaptureVideoPreviewLayer

*captureVideoPreviewLayer;

//自定义UI控件容器

@property

(strong,nonatomic)

UIView

*viewContainer;

//聚焦图标

@property

(strong,nonatomic)

UIImageView

*focusCursor;

//录制时长

@property

(strong,nonatomic)

UILabel

*timeLabel;

//切换前后摄像头

@property

(strong,nonatomic)

UIButton

*switchCameraBtn;

//改变焦距

@property

(strong,nonatomic)

UIButton

*scaleBtn;

//计时器

@property

(strong,nonatomic)

NSTimer

*timer;

@end

@implementation

RecordingVideoViewController

{

@private

NSInteger

_num;

CGFloat

_kCameraScale;

}

-

(UIView

*)viewContainer

{

if

(!_viewContainer)

{

_viewContainer

=

[[UIView

alloc]

initWithFrame:[UIScreen

mainScreen].bounds];

UIButton

*takeButton

=

[UIButton

buttonWithType:UIButtonTypeCustom];

takeButton.backgroundColor

=

[UIColor

redColor];

[takeButton

setTitle:@"start"

forState:UIControlStateNormal];

[takeButton

addTarget:self

action:@selector(takeButtonClick:)

forControlEvents:UIControlEventTouchUpInside];

_timeLabel

=

[[UILabel

alloc]

init];

_timeLabel.textColor

=

[UIColor

redColor];

_timeLabel.textAlignment

=

NSTextAlignmentCenter;

_timeLabel.font

=

[UIFont

boldSystemFontOfSize:20];

_timeLabel.text

=

@"00:00";

_switchCameraBtn

=

[UIButton

buttonWithType:UIButtonTypeCustom];

[_switchCameraBtn

setTitle:@"switch"

forState:UIControlStateNormal];

_switchCameraBtn.backgroundColor

=

[UIColor

redColor];

[_switchCameraBtn

addTarget:self

action:@selector(switchCameraBtnClick)

forControlEvents:UIControlEventTouchUpInside];

_scaleBtn

=

[UIButton

buttonWithType:UIButtonTypeCustom];

[_scaleBtn

setTitle:@"1X"

forState:UIControlStateNormal];

_scaleBtn.backgroundColor

=

[UIColor

redColor];

[_scaleBtn

addTarget:self

action:@selector(scaleBtnClick:)

forControlEvents:UIControlEventTouchUpInside];

[_viewContainer

addSubview:takeButton];

[_viewContainer

addSubview:_timeLabel];

[_viewContainer

addSubview:_scaleBtn];

[_viewContainer

addSubview:_switchCameraBtn];

[takeButton

mas_makeConstraints:^(MASConstraintMaker

*make)

{

make.size.mas_equalTo(CGSizeMake(60,

40));

make.centerX.mas_equalTo(_viewContainer);

make.bottom.mas_equalTo(_viewContainer).offset(-64);

}];

[_timeLabel

mas_makeConstraints:^(MASConstraintMaker

*make)

{

make.centerX.mas_equalTo(_viewContainer);

make.height.mas_equalTo(@30);

make.top.mas_equalTo(_viewContainer);

}];

[_scaleBtn

mas_makeConstraints:^(MASConstraintMaker

*make)

{

make.size.mas_equalTo(CGSizeMake(60,

40));

make.left.mas_equalTo(_viewContainer).offset(10);

make.top.mas_equalTo(_viewContainer);

}];

[_switchCameraBtn

mas_makeConstraints:^(MASConstraintMaker

*make)

{

make.size.mas_equalTo(CGSizeMake(60,

40));

make.top.mas_equalTo(_viewContainer);

make.right.mas_equalTo(_viewContainer).offset(-10);

}];

_focusCursor

=

[[UIImageView

alloc]

init];

kBorder(_focusCursor,

1,

[UIColor

yellowColor]);

_focusCursor.alpha

=

0;

[_viewContainer

addSubview:self.focusCursor];

[_focusCursor

mas_makeConstraints:^(MASConstraintMaker

*make)

{

make.size.mas_equalTo(CGSizeMake(40,

40));

make.center.mas_equalTo(_viewContainer);

}];

}

return

_viewContainer;

}

-

(void)viewDidLoad

{

[super

viewDidLoad];

self.title

=

@"视频录制";

_kCameraScale

=

1.0f;

//初始化会话对象

_captureSession

=

[[AVCaptureSession

alloc]

init];

if

([_captureSession

canSetSessionPreset:AVCaptureSessionPreset1280x720])

{

_captureSession.sessionPreset

=

AVCaptureSessionPreset1280x720;

}

NSError

*error

=

nil;

//获取视频输入对象

AVCaptureDevice

*videoCaptureDevice

=

[self

cameraDeviceWithPosition:(AVCaptureDevicePositionBack)];

if

(!videoCaptureDevice)

{

NSLog(@"获取后置摄像头失败!");

return;

}

_videoCaptureDeviceInput

=

[[AVCaptureDeviceInput

alloc]

initWithDevice:videoCaptureDevice

error:&error];

if

(error)

{

NSLog(@"取得视频设备输入对象时出错");

return;

}

//获取音频输入对象

AVCaptureDevice

*audioCatureDevice

=

[[AVCaptureDevice

devicesWithMediaType:AVMediaTypeAudio]

firstObject];

_audioCaptureDeviceInput

=

[[AVCaptureDeviceInput

alloc]

initWithDevice:audioCatureDevice

error:&error];

if

(error)

{

NSLog(@"取得音频设备输入对象时出错");

return;

}

//初始化设备输出对象

_captureMovieFileOutput

=

[[AVCaptureMovieFileOutput

alloc]

init];

//将设备输入添加到会话中

if

([_captureSession

canAddInput:_videoCaptureDeviceInput])

{

[_captureSession

addInput:_videoCaptureDeviceInput];

[_captureSession

addInput:_audioCaptureDeviceInput];

//防抖功能

AVCaptureConnection

*captureConnection

=

[_captureMovieFileOutput

connectionWithMediaType:AVMediaTypeAudio];

if

([captureConnection

isVideoStabilizationSupported])

{

captureConnection.preferredVideoStabilizationMode

=

AVCaptureVideoStabilizationModeAuto;

}

}

//将设备输出添加到会话中

if

([_captureSession

canAddOutput:_captureMovieFileOutput])

{

[_captureSession

addOutput:_captureMovieFileOutput];

}

//创建视频预览图层

_captureVideoPreviewLayer

=

[[AVCaptureVideoPreviewLayer

alloc]

initWithSession:_captureSession];

self.viewContainer.layer.masksToBounds

=

YES;

_captureVideoPreviewLayer.frame

=

self.viewContainer.bounds;

_captureVideoPreviewLayer.videoGravity

=

AVLayerVideoGravityResizeAspectFill;

[self.view.layer

addSublayer:_captureVideoPreviewLayer];

//显示自定义控件

[self.view

addSubview:self.viewContainer];

//添加点按聚焦手势

UITapGestureRecognizer

*tapGesture

=

[[UITapGestureRecognizer

alloc]initWithTarget:self

action:@selector(tapScreen:)];

[self.viewContainer

addGestureRecognizer:tapGesture];

}

-(void)viewDidAppear:(BOOL)animated{

[super

viewDidAppear:animated];

[self.captureSession

startRunning];

}

-(void)viewDidDisappear:(BOOL)animated{

[super

viewDidDisappear:animated];

[self.captureSession

stopRunning];

[self.timer

invalidate];

self.timer

=

nil;

}

-

(void)viewWillDisappear:(BOOL)animated

{

[super

viewWillDisappear:animated];

[self.captureVideoPreviewLayer

setAffineTransform:CGAffineTransformMakeScale(1,

1)];

}

-

(void)didReceiveMemoryWarning

{

[super

didReceiveMemoryWarning];

}

//开始

+

暂停录制

-

(void)takeButtonClick:(UIButton

*)sender

{

if

([self.captureMovieFileOutput

isRecording])

{

[self.captureMovieFileOutput

stopRecording];

[self.navigationController

popViewControllerAnimated:YES];

}

else

{

AVCaptureConnection

*captureConnection

=

[self.captureMovieFileOutput

connectionWithMediaType:AVMediaTypeVideo];

captureConnection.videoOrientation

=

[self.captureVideoPreviewLayer

connection].videoOrientation;

NSString

*filePath

=

[NSTemporaryDirectory()

stringByAppendingPathComponent:@"Movie.mov"];

NSLog(@"%@",filePath);

[self.captureMovieFileOutput

startRecordingToOutputFileURL:[NSURL

fileURLWithPath:filePath]

recordingDelegate:self];

self.switchCameraBtn.hidden

=

YES;

sender.backgroundColor

=

[UIColor

greenColor];

[sender

setTitle:@"stop"

forState:UIControlStateNormal];

self.timer

=

[NSTimer

scheduledTimerWithTimeInterval:1

target:self

selector:@selector(timeAction)

userInfo:nil

repeats:YES];

[self.timer

setFireDate:[NSDate

distantPast]];

}

}

//切换摄像头

-

(void)switchCameraBtnClick

{

AVCaptureDevicePosition

currentPosition

=

self.videoCaptureDeviceInput.device.position;

AVCaptureDevicePosition

toPosition;

if

(currentPosition

==

AVCaptureDevicePositionUnspecified

||

currentPosition

==

AVCaptureDevicePositionFront)

{

toPosition

=

AVCaptureDevicePositionBack;

}

else

{

toPosition

=

AVCaptureDevicePositionFront;

}

AVCaptureDevice

*toCapturDevice

=

[self

cameraDeviceWithPosition:toPosition];

if

(!toCapturDevice)

{

NSLog(@"获取要切换的设备失败");

return;

}

NSError

*error

=

nil;

AVCaptureDeviceInput

*toVideoDeviceInput

=

[[AVCaptureDeviceInput

alloc]

initWithDevice:toCapturDevice

error:&error];

if

(error)

{

NSLog(@"获取要切换的设备输入失败");

return;

}

//改变会话配置

[self.captureSession

beginConfiguration];

[self.captureSession

removeInput:self.videoCaptureDeviceInput];

if

([self.captureSession

canAddInput:toVideoDeviceInput])

{

[self.captureSession

addInput:toVideoDeviceInput];

self.videoCaptureDeviceInput

=

toVideoDeviceInput;

}

//提交会话配置

[self.captureSession

commitConfiguration];

}

//点按手势

-

(void)tapScreen:(UITapGestureRecognizer

*)tap

{

CGPoint

point

=

[tap

locationInView:self.viewContainer];

//将界面point对应到摄像头point

CGPoint

cameraPoint

=

[self.captureVideoPreviewLayer

captureDevicePointOfInterestForPoint:point];

//设置聚光动画

self.focusCursor.center

=

point;

self.focusCursor.transform

=

CGAffineTransformMakeScale(1.5,

1.5);

self.focusCursor.alpha

=

1.0f;

[UIView

animateWithDuration:1

animations:^{

self.focusCursor.transform

=

CGAffineTransformIdentity;

}

completion:^(BOOL

finished)

{

self.focusCursor.alpha

=

0.0f;

}];

//设置聚光点坐标

[self

focusWithMode:AVCaptureFocusModeAutoFocus

exposureMode:AVCaptureExposureModeAutoExpose

atPoint:cameraPoint];

}

/**设置聚焦点*/

-(void)focusWithMode:(AVCaptureFocusMode)focusMode

exposureMode:(AVCaptureExposureMode)exposureMode

atPoint:(CGPoint)point{

AVCaptureDevice

*captureDevice=

[self.videoCaptureDeviceInput

device];

NSError

*error

=

nil;

//设置设备属性必须先解锁

然后加锁

if

([captureDevice

lockForConfiguration:&error])

{

if

([captureDevice

isFocusModeSupported:focusMode])

{

[captureDevice

setFocusMode:focusMode];

}

if

([captureDevice

isFocusPointOfInterestSupported])

{

[captureDevice

setFocusPointOfInterest:point];

}

//

//曝光

//

if

([captureDevice

isExposureModeSupported:exposureMode])

{

//

[captureDevice

setExposureMode:exposureMode];

//

}

//

if

([captureDevice

isExposurePointOfInterestSupported])

{

//

[captureDevice

setExposurePointOfInterest:point];

//

}

//

//闪光灯模式

//

if

([captureDevice

isFlashModeSupported:AVCaptureFlashModeAuto])

{

//

[captureDevice

setFlashMode:AVCaptureFlashModeAuto];

//

}

//加锁

[captureDevice

unlockForConfiguration];

}else{

NSLog(@"设置设备属性过程发生错误,错误信息:%@",error.localizedDescription);

}

}

//调整焦距

-(void)scaleBtnClick:(UIButton

*)sender

{

_kCameraScale

+=

0.5;

if(_kCameraScale

>

3.0)

{

_kCameraScale

=

1.0;

}

//改变焦距

AVCaptureDevice

*videoDevice

=

self.videoCaptureDeviceInput.device;

NSError

*error

=

nil;

if

([videoDevice

lockForConfiguration:&error])

{

[videoDevice

setVideoZoomFactor:_kCameraScale];

[videoDevice

unlockForConfiguration];

[sender

setTitle:[NSString

stringWithFormat:@"%lgX",_kCameraScale]

forState:UIControlStateNormal];

[CATransaction

begin];

[CATransaction

setAnimationDuration:0.25];

[self.captureVideoPreviewLayer

setAffineTransform:CGAffineTransformMakeScale(_kCameraScale,

_kCameraScale)];

[CATransaction

commit];

}

else

{

NSLog(@"修改设备属性失败!")

}

}

#pragma

mark

AVCaptureFileOutputRecordingDelegate

-

(void)captureOutput:(AVCaptureFileOutput

*)captureOutput

didStartRecordingToOutputFileAtURL:(NSURL

*)fileURL

fromConnections:(NSArray

*)connections

{

NSLog(@"开始录制");

}

-

(void)captureOutput:(AVCaptureFileOutput

*)captureOutput

didFinishRecordingToOutputFileAtURL:(NSURL

*)outputFileURL

fromConnections:(NSArray

*)connections

error:(NSError

*)error

{

NSLog(@"录制结束");

ALAssetsLibrary

*assetsLibrary

=

[[ALAssetsLibrary

alloc]

init];

[assetsLibrary

writeVideoAtPathToSavedPhotosAlbum:outputFileURL

completionBlock:^(NSURL

*assetURL,

NSError

*error)

{

if

(error)

{

NSLog(@"保存视频到相簿过程中发生错误,错误信息:%@",error.localizedDescription);

}

}];

}

//录制计时

-

(void)timeAction

{

self.timeLabel.text

=

[NSString

stringWithFormat:@"%.2ld:%.2ld",_num/60,_num%60];

_num

++;

}

/**取得指定位置的摄像头*/

-

(AVCaptureDevice

*)cameraDeviceWithPosition:(AVCaptureDevicePosition

)position{

NSArray

*cameras

=

[AVCaptureDevice

devicesWithMediaType:AVMediaTypeVideo];

for

(AVCaptureDevice

*camera

in

cameras)

{

if

([camera

position]

==

position)

{

return

camera;

}

}

return

nil;

}

@end参考代码:#import

"VideoTestViewController.h"

#import

<AVFoundation/AVFoundation.h>

#import

<AssetsLibrary/AssetsLibrary.h>

typedef

void(^PropertyChangeBlock)(AVCaptureDevice

*captureDevice);

@interface

VideoTestViewController

()<AVCaptureFileOutputRecordingDelegate>//视频文件输出代理

@property

(strong,nonatomic)

AVCaptureSession

*captureSession;//负责输入和输出设备之间的数据传递

@property

(strong,nonatomic)

AVCaptureDeviceInput

*captureDeviceInput;//负责从AVCaptureDevice获得输入数据

@property

(strong,nonatomic)

AVCaptureMovieFileOutput

*captureMovieFileOutput;//视频输出流

@property

(strong,nonatomic)

AVCaptureVideoPreviewLayer

*captureVideoPreviewLayer;//相机拍摄预览图层

@property

(assign,nonatomic)

BOOL

enableRotation;//是否允许旋转(注意在视频录制过程中禁止屏幕旋转)

@property

(assign,nonatomic)

CGRect

*lastBounds;//旋转的前大小

@property

(assign,nonatomic)

UIBackgroundTaskIdentifier

backgroundTaskIdentifier;//后台任务标识

@property

(strong,nonatomic)

UIView

*viewContainer;

@property

(strong,nonatomic)

UIButton

*takeButton;//拍照按钮

@property

(strong,nonatomic)

UIImageView

*focusCursor;

//聚焦光标

@end

@implementation

VideoTestViewController

#pragma

mark

-

控制器视图方法

-

(void)viewDidLoad

{

[super

viewDidLoad];

}

-(void)viewWillAppear:(BOOL)animated{

[super

viewWillAppear:animated];

//初始化会话

_captureSession=[[AVCaptureSession

alloc]init];

if

([_captureSession

canSetSessionPreset:AVCaptureSessionPreset1280x720])

{//设置分辨率

_captureSession.sessionPreset=AVCaptureSessionPreset1280x720;

}

//获得输入设备

AVCaptureDevice

*captureDevice=[self

getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置摄像头

if

(!captureDevice)

{

NSLog(@"取得后置摄像头时出现问题.");

return;

}

//添加一个音频输入设备

AVCaptureDevice

*audioCaptureDevice=[[AVCaptureDevice

devicesWithMediaType:AVMediaTypeAudio]

firstObject];

NSError

*error=nil;

//根据输入设备初始化设备输入对象,用于获得输入数据

_captureDeviceInput=[[AVCaptureDeviceInput

alloc]initWithDevice:captureDevice

error:&error];

if

(error)

{

NSLog(@"取得设备输入对象时出错,错误原因:%@",error.localizedDescription);

return;

}

AVCaptureDeviceInput

*audioCaptureDeviceInput=[[AVCaptureDeviceInput

alloc]initWithDevice:audioCaptureDevice

error:&error];

if

(error)

{

NSLog(@"取得设备输入对象时出错,错误原因:%@",error.localizedDescription);

return;

}

//初始化设备输出对象,用于获得输出数据

_captureMovieFileOutput=[[AVCaptureMovieFileOutput

alloc]init];

//将设备输入添加到会话中

if

([_captureSession

canAddInput:_captureDeviceInput])

{

[_captureSession

addInput:_captureDeviceInput];

[_captureSession

addInput:audioCaptureDeviceInput];

AVCaptureConnection

*captureConnection=[_captureMovieFileOutput

connectionWithMediaType:AVMediaTypeVideo];

if

([captureConnection

isVideoStabilizationSupported

])

{

captureConnection.preferredVideoStabilizationMode=AVCaptureVideoStabilizationModeAuto;

}

}

//将设备输出添加到会话中

if

([_captureSession

canAddOutput:_captureMovieFileOutput])

{

[_captureSession

addOutput:_captureMovieFileOutput];

}

//创建视频预览层,用于实时展示摄像头状态

_captureVideoPreviewLayer=[[AVCaptureVideoPreviewLayer

alloc]initWithSession:self.captureSession];

CALayer

*layer=self.viewContainer.layer;

layer.masksToBounds=YES;

_captureVideoPreviewLayer.frame=layer.bounds;

_captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;//填充模式

//将视频预览层添加到界面中

//[layer

addSublayer:_captureVideoPreviewLayer];

[layer

insertSublayer:_captureVideoPreviewLayer

below:self.focusCursor.layer];

_enableRotation=YES;

[self

addNotificationToCaptureDevice:captureDevice];

[self

addGenstureRecognizer];

}

-(void)viewDidAppear:(BOOL)animated{

[super

viewDidAppear:animated];

[self.captureSession

startRunning];

}

-(void)viewDidDisappear:(BOOL)animated{

[super

viewDidDisappear:animated];

[self.captureSession

stopRunning];

}

-

(void)didReceiveMemoryWarning

{

[super

didReceiveMemoryWarning];

}

-(BOOL)shouldAutorotate{

return

self.enableRotation;

}

////屏幕旋转时调整视频预览图层的方向

//-(void)willTransitionToTraitCollection:(UITraitCollection

*)newCollection

withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{

//

[super

willTransitionToTraitCollection:newCollection

withTransitionCoordinator:coordinator];

////

NSLog(@"%i,%i",newCollection.verticalSizeClass,newCollection.horizontalSizeClass);

//

UIInterfaceOrientation

orientation

=

[[UIApplication

sharedApplication]

statusBarOrientation];

//

NSLog(@"%i",orientation);

//

AVCaptureConnection

*captureConnection=[self.captureVideoPreviewLayer

connection];

//

captureConnection.videoOrientation=orientation;

//

//}

//屏幕旋转时调整视频预览图层的方向

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation

duration:(NSTimeInterval)duration{

AVCaptureConnection

*captureConnection=[self.captureVideoPreviewLayer

connection];

captureConnection.videoOrientation=(AVCaptureVideoOrientation)toInterfaceOrientation;

}

//旋转后重新设置大小

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{

_captureVideoPreviewLayer.frame=self.viewContainer.bounds;

}

-(void)dealloc{

[self

removeNotification];

}

#pragma

mark

-

UI方法

#pragma

mark

视频录制

-

(void)takeButtonClick:(UIButton

*)sender

{

//根据设备输出获得连接

AVCaptureConnection

*captureConnection=[self.captureMovieFileOutput

connectionWithMediaType:AVMediaTypeVideo];

//根据连接取得设备输出的数据

if

(![self.captureMovieFileOutput

isRecording])

{

self.enableRotation=NO;

//如果支持多任务则则开始多任务

if

([[UIDevice

currentDevice]

isMultitaskingSupported])

{

self.backgroundTaskIdentifier=[[UIApplication

sharedApplication]

beginBackgroundTaskWithExpirationHandler:nil];

}

//预览图层和视频方向保持一致

captureConnection.videoOrientation=[self.captureVideoPreviewLayer

connection].videoOrientation;

NSString

*outputFielPath=[NSTemporaryDirectory()

stringByAppendingString:@"myMovie.mov"];

NSLog(@"save

path

is

:%@",outputFielPath);

NSURL

*fileUrl=[NSURL

fileURLWithPath:outputFielPath];

[self.captureMovieFileOutput

startRecordingToOutputFileURL:fileUrl

recordingDelegate:self];

}

else{

[self.captureMovieFileOutput

stopRecording];//停止录制

}

}

#pragma

mark

切换前后摄像头

-

(void)toggleButtonClick:(UIButton

*)sender

{

AVCaptureDevice

*currentDevice=[self.captureDeviceInput

device];

AVCaptureDevicePosition

currentPosition=[currentDevice

position];

[self

removeNotificationFromCaptureDevice:currentDevice];

AVCaptureDevice

*toChangeDevice;

AVCaptureDevicePosition

toChangePosition=AVCaptureDevicePositionFront;

if

(currentPosition==AVCaptureDevicePositionUnspecified||currentPosition==AVCaptureDevicePositionFront)

{

toChangePosition=AVCaptureDevicePositionBack;

}

toChangeDevice=[self

getCameraDeviceWithPosition:toChangePosition];

[self

addNotificationToCaptureDevice:toChangeDevice];

//获得要调整的设备输入对象

AVCaptureDeviceInput

*toChangeDeviceInput=[[AVCaptureDeviceInput

alloc]initWithDevice:toChangeDevice

error:nil];

//改变会话的配置前一定要先开启配置,配置完成后提交配置改变

[self.captureSession

beginConfiguration];

//移除原有输入对象

[self.captureSession

removeInput:self.captureDeviceInput];

//添加新的输入对象

if

([self.captureSession

canAddInput:toChangeDeviceInput])

{

[self.captureSession

addInput:toChangeDeviceInput];

self.captureDeviceInput=toChangeDeviceInput;

}

//提交会话配置

[self.captureSession

commitConfiguration];

}

#pragma

mark

-

视频输出代理

-(void)captureOutput:(AVCaptureFileOutput

*)captureOutput

didStartRecordingToOutputFileAtURL:(NSURL

*)fileURL

fromConnections:(NSArray

*)connections{

NSLog(@"开始录制...");

}

-(void)captureOutput:(AVCaptureFileOutput

*)captureOutput

didFinishRecordingToOutputFileAtURL:(NSURL

*)outputFileURL

fromConnections:(NSArray

*)connections

error:(NSError

*)error{

NSLog(@"视频录制完成.");

//视频录入完成之后在后台将视频存储到相簿

self.enableRotation=YES;

UIBackgroundTaskIdentifier

lastBackgroundTaskIdentifier=self.backgroundTaskIdentifier;

self.backgroundTaskIdentifier=UIBackgroundTaskInvalid;

ALAssetsLibrary

*assetsLibrary=[[ALAssetsLibrary

alloc]init];

[assetsLibrary

writeVideoAtPathToSavedPhotosAlbum:outputFileURL

completionBlock:^(NSURL

*assetURL,

NSError

*error)

{

if

(error)

{

NSLog(@"保存视频到相簿过程中发生错误,错误信息:%@",error.localizedDescription);

}

if

(lastBackgroundTaskIdentifier!=UIBackgroundTaskInvalid)

{

[[UIApplication

sharedApplication]

endBackgroundTask:lastBackgroundTaskIdentifier];

}

NSLog(@"成功保存视频到相簿.");

}];

}

#pragma

mark

-

通知

/**

*

给输入设备添加通知

*/

-(void)addNotificationToCaptureDevice:(AVCaptureDevice

*)captureDevice{

//注意添加区域改变捕获通知必须首先设置设备允许捕获

[self

changeDeviceProperty:^(AVCaptureDevice

*captureDevice)

{

captureDevice.subjectAreaChangeMonitoringEnabled=YES;

}];

NSNotificationCenter

*notificationCenter=

[NSNotificationCenter

defaultCenter];

//捕获区域发生改变

[notificationCenter

addObserver:self

selector:@selector(areaChange:)

name:AVCaptureDeviceSubjectAreaDidChangeNotification

object:captureDevice];

}

-(void)removeNotificationFromCaptureDevice:(AVCaptureDevice

*)captureDevice{

NSNotificationCenter

*notificationCenter=

[NSNotificationCenter

defaultCenter];

[notificationCenter

removeObserver:self

name:AVCaptureDeviceSubjectAreaDidChangeNotification

object:captureDevice];

}

/**

*

移除所有通知

*/

-(void)removeNotification{

NSNotificationCenter

*notificationCenter=

[NSNotificationCenter

defaultCenter];

[notificationCenter

removeObserver:self];

}

-(void)addNotificationToCaptureSession:(AVCaptureSession

*)captureSession{

NSNotificationCenter

*notificationCenter=

[NSNotificationCenter

defaultCenter];

//会话出错

[notificationCenter

addObserver:self

selector:@selector(sessionRuntimeError:)

name:AVCaptureSessionRuntimeErrorNotification

object:captureSession];

}

/**

*

设备连接成功

*

*

@param

notification

通知对象

*/

-(void)deviceConnected:(NSNotification

*)notification{

NSLog(@"设备已连接...");

}

/**

*

设备连接断开

*

*

@param

notification

通知对象

*/

-(void)deviceDisconnected:(NSNotification

*)notification{

NSLog(@"设备已断开.");

}

/**

*

捕获区域改变

*

*

@param

notification

通知对象

*/

-(void)areaChange:(NSNotification

*)notification{

NSLog(@"捕获区域改变...");

}

/**

*

会话出错

*

*

@param

notification

通知对象

*/

-(void)sessionRuntimeError:(NSNotification

*)notification{

NSLog(@"会话发生错误.");

}

#pragma

mark

-

私有方法

/**

*

取得指定位置的摄像头

*

*

@param

position

摄像头位置

*

*

@return

摄像头设备

*/

-(AVCaptureDevice

*)getCameraDeviceWithPosition:(AVCaptureDevicePosition

)position{

NSArray

*cameras=

[AVCaptureDevice

devicesWithMediaType:AVMediaTypeVideo];

for

(AVCaptureDevice

*camera

in

cameras)

{

if

([camera

position]==position)

{

return

camera;

}

}

return

nil;

}

/**

*

改变设备属性的统一操作方法

*

*

@param

propertyChange

属性改变操作

*/

-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{

AVCaptureDevice

*captureDevice=

[self.captureDeviceInput

device];

NSError

*error;

//注意改变设备属性前一定要首先调用lockForConfiguration:调用完之后使用unlockForConfiguration方法解锁

if

([captureDevice

lockForConfiguration:&error])

{

propertyChange(captureDevice);

[captureDevice

unlockForConfiguration];

}else{

NSLog(@"设置设备属性过程发生错误,错误信息:%@",error.localizedDescription);

}

}

/**

*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论