AVFoundation 初步探索

AVFoundation 學習之初始

在目前iOS的技術棧裏面,視頻流一直是比較主流的一個學習方向,今天,在這寫上一些上週在AVFoundation框架下,所學所講的。數組

咱們在理解AVFoundation 這個框架的時候,要學會 Apple 對這個框架有什麼做用:bash

照片/視頻的捕捉 小視頻/直播session

捕捉會話

  • AVCaptureSession 設備捕捉會話框架

  • AVCaptureDevice 捕捉設備異步

  • AVCaptureDeviceInput 捕捉設備輸入async

  • AVCaptureFileOutput (一個抽象類) 多類型音頻文件ide

    • AVCaptureStillImageOutput 靜態圖片輸出
    • AVCaptureFileOutput 文件輸出
    • AVCaptureMovieFileOutput 靜態視頻文件輸出
    • AVCaptureAudioFileOutput 音頻文件輸出
    • AVCaptureVideoDataOutput 視頻文件輸出
  • 捕捉鏈接 AVCaptureConnection 創建輸入輸出的鏈接學習

  • AVCaptureVideoPreviewLayer 渲染捕捉塗層 預覽內容ui

攝像頭座標 && 手機座標 相互轉換

  • captureDevicePointOfInterestForPoint 獲取到屏幕的座標系的point 轉換成物理設備的座標數據
  • PointForCaptureDevicePointOfInterest 獲取到物理設備座標系 轉化爲手機屏幕的座標

##乾貨 直接上代碼 寫註釋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);
    

複製代碼

session

做爲捕捉音視頻的鏈接者,咱們能對視頻的狀態作出處理 以及切換

例如:

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設備出錯 的處理機制
    }


複製代碼
相關文章
相關標籤/搜索