天天看點

AVFoundation學習Demo--拍攝視訊初始化�預覽畫面拍攝視訊增強攝像功能

通過 拍攝照片Demo 的學習,我們學會了AVCaptureSession的基本使用。現在,同樣使用AVCaptureSession類,隻需要做微小的修改就可以完成視訊拍攝。

初始化�預覽畫面

聲明屬性

首先,我們要聲明拍攝所必須的屬性:

@property (nonatomic, strong) AVCaptureSession *captureSession;

@property (nonatomic, strong) AVCaptureDevice *videoDevice;

@property (nonatomic, strong) AVCaptureDevice *audioDevice;

@property (nonatomic, strong) AVCaptureDeviceInput *videoInput;

@property (nonatomic, strong) AVCaptureDeviceInput *audioInput;

@property (nonatomic, strong) AVCaptureMovieFileOutput *movieFileOutput;

@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
           

因為視訊會包含音頻資訊,是以比拍攝圖檔多出了音頻裝置(audioDevice)和音頻輸入(audioInput)。而我們的輸出類由AVCaptureStillImageOutput變成了AVCaptureMovieFileOutput,他們同樣都是AVCaptureOutput的子類。

捕捉會話初始化

在拍攝視訊前,需要初始化捕捉會話(AVCaptureSession):

- (void)setupCaptureSession {
    // 1.擷取視訊裝置
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if (device.position == AVCaptureDevicePositionBack) {
            self.videoDevice = device;
            break;
        }
    }
    // 2.擷取音頻裝置
    self.audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    // 3.建立視訊輸入
    NSError *error = nil;
    self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:self.videoDevice error:&error];
    if (error) {
        return;
    }
    // 4.建立音頻輸入
    self.audioInput = [AVCaptureDeviceInput deviceInputWithDevice:self.audioDevice error:&error];
    if (error) {
        return;
    }
    // 5.建立視訊輸出
    self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
    // 6.建立會話
    self.captureSession = [[AVCaptureSession alloc] init];
    self.captureSession.sessionPreset = AVCaptureSessionPreset1280x720;
    if ([self.captureSession canAddInput:self.videoInput]) {
        [self.captureSession addInput:self.videoInput];
    }
    if ([self.captureSession canAddInput:self.audioInput]) {
        [self.captureSession addInput:self.audioInput];
    }
    if ([self.captureSession canAddOutput:self.movieFileOutput]) {
        [self.captureSession addOutput:self.movieFileOutput];
    }
    // 7.預覽畫面
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
    [self.previewView.layer addSublayer:self.previewLayer];
}
           

看到這個方法應該很熟悉了吧,和拍攝照片的初始化話幾乎沒有差別。需要注意的是第6步sessionPreset設為了AVCaptureSessionPreset1280x720,也就是輸出720p的視訊。通過查詢文檔,還有很多不同分辨率可供選擇。

還記得開始和結束會話的兩個方法嗎?�startRunning和stopRunning,真是太好記了:

- (void)startSession {
    if(![self.captureSession isRunning]) {
        [self.captureSession startRunning];
    }
}
- (void)stopSession {
    if([self.captureSession isRunning]) {
        [self.captureSession stopRunning];
    }
}
           

最後,在viewDidLoad中調用上文的兩個方法:

[self setupCaptureSession];
    [self startSession];
           

真機運作,就可以看到拍攝預覽畫面了。

拍攝視訊

完成了初始化工作, 拍攝視訊部分,我們隻需要調用startRecordingToOutputFileURL:recordingDelegate:方法就可以實作了。其中,參數url是為視訊指定的輸出路徑。

下面我們要為錄制按鈕建立兩個Action,touch down時開始拍攝視訊,touch up時結束拍攝。

touch down時,調用startRecord方法:

- (void)startRecord {
    [self.movieFileOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:[self videoPath]] recordingDelegate:self];
}
           

touch up時,調用stopRecord方法:

- (void)stopRecord {
    if ([self.movieFileOutput isRecording]) {
        [self.movieFileOutput stopRecording];
    }
}
           

我們注意到,開始拍攝時,調用了videoPath方法為視訊生成一個輸出位址。這個方法使用目前時間戳作為唯一的視訊檔案名:

- (NSString *)videoPath {
    NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *moviePath = [basePath stringByAppendingPathComponent:
   [NSString stringWithFormat:@"%f.mp4",[NSDate date].timeIntervalSince1970]];
    return moviePath;
}
           

最後我們,還要實作AVCaptureFileOutputRecordingDelegate代理。拍攝完成後,系統會觸發captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法。我們可以通過outputFileURL參數通路拍攝好的視訊檔案。

增強攝像功能

拍攝視訊和照片的一些進階功能原理是一緻的,這裡我隻将上個Demo中�一塊代碼拷貝了過來,不用做任何修改就可實作攝像頭切換。其他的進階設定可以查閱文檔�自行探索。

Demo位址:

https://github.com/WorthyZhang/WZMediaDemo

繼續閱讀