在目前iOS的技術棧裏面,視頻流一直是比較主流的一個學習方向,今天,在這寫上一些上週在AVFoundation框架下,所學所講的。數組
咱們在理解AVFoundation 這個框架的時候,要學會 Apple 對這個框架有什麼做用:bash
照片/視頻的捕捉 小視頻/直播session
AVCaptureSession 設備捕捉會話框架
AVCaptureDevice 捕捉設備異步
AVCaptureDeviceInput 捕捉設備輸入async
AVCaptureFileOutput (一個抽象類) 多類型音頻文件ide
捕捉鏈接 AVCaptureConnection 創建輸入輸出的鏈接學習
AVCaptureVideoPreviewLayer 渲染捕捉塗層 預覽內容ui
##乾貨 直接上代碼 寫註釋spa
//初始化 AVCaptureSession 對象
self.captureSession = [[AVCaptureSession alloc] init];
//設置高分辨率 其餘參數 請查看 sessionPreset 內的設置
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
// 獲取到設備 MediaType 表明的是獲取設備的哪一種類型
AVCaptureDevice * videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//輸入設備 將設備轉化爲 AVCaptureDeviceInput
AVCaptureDeviceInput * videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
if (videoDevice) {
//判斷是否有效
if ([self.captureSession canAddInput:videoDeviceInput]) {
[self.captureSession addInput:videoDeviceInput];
}
}
// 獲取設備的音頻輸出處理裝置
AVCaptureDevice * audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput * audiodeViceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
if (audiodeViceInput) {
if ([self.captureSession canAddInput:audiodeViceInput]) {
[self.captureSession addInput:audiodeViceInput];
}
}
//靜態圖片輸出對象的初始化
self.imageOutput = [[AVCaptureStillImageOutput alloc]init];
//設置 視屏的格式 JPEG
self.imageOutput.outputSettings = @{AVVideoCodecKey:AVVideoCodecTypeJPEG};
if ([self.captureSession canAddOutput:self.imageOutput]) {
[self.captureSession canAddOutput:self.imageOutput];
}
//建立一個文件
self.movieOutPut = [[AVCaptureMovieFileOutput alloc] init];
if ([self.captureSession canAddOutput:self.movieOutPut]) {
[self.captureSession addOutput:self.movieOutPut];
}
self.videoQuect = dispatch_queue_create("jz.videoqueue", NULL);
複製代碼
做爲捕捉音視頻的鏈接者,咱們能對視頻的狀態作出處理 以及切換
例如:
self.captureSession isRunning // 判斷的就是當前的session 是不是在運行中
我的建議同步調用會損耗必定的時間,則用異步的方式處理
dispatch_async(self.videoQueue, ^{
[self.captureSession stopRunning];
});
// 同道理 開始的時候 可檢測
if (![self.captureSession isRunning])
{
dispatch_async(self.videoQueue, ^{
[self.captureSession startRunning];
});
}
複製代碼
// 判斷設備 是否擁有物理設備
<!-- NSArray * devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
獲取當前設備的數組設備 而後進行判斷
for (AVCaptureDevice *device in devices)
{
if (device.position == position) {
return device; //獲取到我當前的 position 而後返回設備
}
}
-->
// 判斷設備 當前的物理設備數
//獲取當前視頻捕捉設備的數量
NSInteger deviceCount = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
// 獲取當前的活躍設備
self.videoDeviceInput.device
// 獲取當前先後置攝像頭的處理
AVCaptureDevice *device = nil;
if(deviceCount > 1)
{
//返回獲取到逆向切換的物理設備
if (self.videoDeviceInput.device.position == AVCaptureDevicePositionBack)
{
//AVCaptureDevicePositionFront 後置攝像頭
}
else
{
//AVCaptureDevicePositionBack 前置攝像頭
}
}
複製代碼
// 生成當前的輸入源 videoDevice 是你當前的切換的設備信息
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
//判斷videoInput 是否爲nil
if (videoInput)
{
//標註原配置變化開始
[self.captureSession beginConfiguration];
//將捕捉會話中,本來的捕捉輸入設備移除
[self.captureSession removeInput:self.activeVideoInput];
//判斷新的設備是否能加入
if ([self.captureSession canAddInput:videoInput])
{
//能加入成功,則將videoInput 做爲新的視頻捕捉設備
[self.captureSession addInput:videoInput];
//將得到設備 改成 videoInput
self.activeVideoInput = videoInput;
}else
{
//若是新設備,沒法加入。則將本來的視頻捕捉設備從新加入到捕捉會話中
[self.captureSession addInput:self.activeVideoInput];
}
//配置完成後, AVCaptureSession commitConfiguration 會分批的將全部變動整合在一塊兒。
[self.captureSession commitConfiguration];
}
else
{
//建立input設備出錯 的處理機制
}
複製代碼