利用AVCaptureSession实现拍照与录像功能
立即解锁
发布时间: 2025-08-25 01:34:51 阅读量: 1 订阅数: 19 

### 利用 AVCaptureSession 实现拍照与录像功能
在开发涉及相机功能的应用时,`AVCaptureSession` 是一个强大的工具,它可以帮助我们实现拍照和录像等功能。下面将详细介绍如何使用 `AVCaptureSession` 实现这些功能。
#### 1. 利用 AVCaptureSession 拍摄静态图像
在之前的基础上,我们要扩展项目,实现拍摄静态图像并保存到设备相册的功能。
##### 1.1 项目准备
- **添加框架**:在项目中添加 `AssetsLibrary.framework`,该框架用于将照片写入相册。
- **添加权限描述**:在应用的 `Info.plist` 文件中添加 `NSPhotoLibraryUsageDescription` 键,并简要说明应用访问相册的原因,例如 “Testing AVCaptureSession”。
##### 1.2 添加拍摄按钮
- 在视图控制器的故事板视图中添加一个标题为 “Capture” 的按钮,并为该按钮创建一个名为 “capture” 的动作。
- 为确保按钮随屏幕大小调整,选择按钮,从故事板编辑器屏幕右下角的 “Resolve Auto Layout Issues” 菜单中选择 “Add Missing Constraints”。
##### 1.3 修改代码
- **ViewController.h 文件**:导入 `AssetsLibrary` 框架,并添加一个属性来保存静态图像输出实例。
```objc
//
// ViewController.h
// Recipe 9-6: Taking Still Images With AVCaptureSession
//
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) AVCaptureSession *captureSession;
@property (strong, nonatomic) AVCaptureDeviceInput *videoInput;
@property (strong, nonatomic) AVCaptureStillImageOutput *stillImageOutput;
- (IBAction)capture:(id)sender;
@end
```
- **ViewController.m 文件**:在 `viewDidLoad` 方法中添加代码,分配并初始化静态图像输出对象,并将其连接到捕获会话。
```objc
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.captureSession = [[AVCaptureSession alloc] init];
//Optional: self.captureSession.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureDevice *device =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (self.videoInput)
{
[self.captureSession addInput:self.videoInput];
}
else
{
NSLog(@"Input Error: %@", error);
}
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *stillImageOutputSettings =
[[NSDictionary alloc] initWithObjectsAndKeys:
AVVideoCodecJPEG, AVVideoCodecKey, nil];
[self.stillImageOutput setOutputSettings:stillImageOutputSettings];
[self.captureSession addOutput:self.stillImageOutput];
AVCaptureVideoPreviewLayer *previewLayer =
[AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
UIView *aView = self.view;
previewLayer.frame =
CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-70);
[aView.layer addSublayer:previewLayer];
}
```
##### 1.4 实现拍摄方法
- **`capture` 动作方法**:调用 `captureStillImage` 方法。
```objc
- (IBAction)capture:(id)sender
{
[self captureStillImage];
}
```
- **`captureStillImage` 方法**:
```objc
- (void) captureStillImage
{
AVCaptureConnection *stillImageConnection =
[self.stillImageOutput.connections objectAtIndex:0];
if ([stillImageConnection isVideoOrientationSupported])
[stillImageConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
[self.stillImageOutput
captureStillImageAsynchronouslyFromConnection:stillImageConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
{
if (imageDataSampleBuffer != NULL)
{
NSData *imageData = [AVCaptureStillImageOutput
jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[library writeImageToSavedPhotosAlbum:[image CGImage]
orientation:(ALAssetOrientation)[image imageOrientation]
completionBlock:^(NSURL *assetURL, NSError *error)
{
UIAlertView *alert;
if (!error)
{
alert = [[UIAlertView alloc] initWithTitle:@"Photo Saved"
message:@"The photo was successfully saved to your photos library"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
}
else
{
alert = [[UIAlertView alloc] initWithTitle:@"Error Saving Photo"
message:@"The photo was not saved to your photos library"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
}
[alert show];
}
];
}
else
{
NSLog(@"Error capturing still image: %@", error);
}
}
];
}
```
#### 2. 利用 AVCaptureSession 录制视频
接下来,我们要扩展应用,实现录制视频的功能,并允许用户在拍照和录像模式之间切换。
##### 2.1 添加视频录制模式
- 在用户界面中添加一个分段控件,将两个分段的默认文本改为 “Take Photo” 和 “Record Video”,使视图类似于图 9 - 13。
- 为分段控件和按钮添加输出口,分别命名为 “modeControl” 和 “captureButton”,并为分段控件的值变化事件创建一个名为 “updateMode” 的动作。
##### 2.2 修改代码
- **ViewController.h 文件**:添加音频输入和电影文件输出的属性,并实现 `AVCaptureFileOutputRecordingDelegate` 协议。
```objc
//
// ViewController.h
// Recipe 9-7 Recording Video With AVCaptureSession
//
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface ViewController : UIViewController <AVCaptureFileOutputRecordingDelegate>
@property (strong, nonatomic) AVCaptureSession *captureSession;
@property (strong, nonatomic) AVCaptureDeviceInput *videoInput;
@property (strong, nonatomic) AVCaptureDeviceInput *audioInput;
@property (strong, nonatomic) AVCaptureStillImageOutput *stillImageOutput;
@property (strong, nonatomic) AVCaptureMovieFileOutput *movieOutput;
@property (weak, nonatomic) IBOutlet UIButton *captureButton;
@property (weak, nonatomic) IBOutlet UISegmentedControl *modeControl;
- (IBAction)capture:(id)sender;
- (IBAction)updateMode:(id)sender;
@end
```
- **ViewController.m 文件**:
- **`viewDidLoad` 方法**:设置音频输入对象、电影文件输出对象,并调整预览层的大小。
```objc
- (void)viewDidLoad
{
[super viewDidLoad];
self.captureSession = [[AVCaptureSession alloc] init];
//Optional: self.captureSession.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureDevice *videoDevice =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *audioDevice =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *error = nil;
self.videoInput =
[AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
self.audioInput =
[[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:&error];
if (self.videoInput)
{
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *stillImageOutputSettings = [[NSDictionary alloc]
initWithObjectsAndKeys:AVVideoCodecJPEG,
AVVideoCodecKey, nil];
[self.stillImageOutput setOutputSettings:stillImageOutputSettings];
self.movieOutput = [[AVCaptureMovieFileOutpu
```
0
0
复制全文
相关推荐









