iOS 1.音視頻採集

音頻採集參數git

  • 一、採樣率(samplerate):採樣就是把模擬信號數字化的過程,採樣頻率越高,記錄這一段音頻信號所用的數據量就越大,同時音頻質量也就越高。github

  • 二、位寬:每個採樣點都須要用一個數值來表示大小,這個數值的數據類型大小能夠是:4bit、8bit、16bit、32bit 等等,位數越多,表示得就越精細,聲音質量天然就越好,而數據量也會成倍增大。咱們在音頻採樣過程當中經常使用的位寬是 8bit 或者 16bit。算法

  • 三、聲道數(channels):因爲音頻的採集和播放是能夠疊加的,所以,能夠同時從多個音頻源採集聲音,並分別輸出到不一樣的揚聲器,故聲道數通常表示聲音錄製時的音源數量或回放時相應的揚聲器數量。聲道數爲 1 和 2 分別稱爲單聲道和雙聲道,是比較常見的聲道參數。緩存

  • 音頻幀(frame):音頻跟視頻很不同,視頻每一幀就是一張圖像,音頻數據是流式的,自己沒有明確的一幀幀的概念,在實際的應用中,爲了音頻算法處理/傳輸的方便,通常約定俗成取 2.5ms~60ms 爲單位的數據量爲一幀音頻。這個時間被稱之爲「採樣時間」,其長度沒有特別的標準,它是根據編解碼器和具體應用的需求來決定的。框架

根據以上定義,咱們能夠計算一下一幀音頻幀的大小。假設某音頻信號是採樣率爲 8kHz、雙通道、位寬爲 16bit,20ms 一幀,則一幀音頻數據的大小爲: size = 8000 x 2 x 16bit x 0.02s = 5120 bit = 640 byteide

視頻採集參數性能

  • 一、圖像傳輸格式:通用影像傳輸格式(Common Intermediate Format)是視訊會議(video conference)中常使用的影像傳輸格式。ui

  • 二、圖像格式:一般採用 YUV 格式存儲原始數據信息,其中包含用 8 位表示的黑白圖像灰度值,以及可由 RGB 三種色彩組合成的彩色圖像。spa

  • 三、傳輸通道:正常狀況下視頻的拍攝只需 1 路通道,隨着 VR 和 AR 技術的日漸成熟,爲了拍攝一個完整的 360° 視頻,可能須要經過不一樣角度拍攝,而後通過多通道傳輸後合成。代理

  • 四、分辨率:隨着設備屏幕尺寸的日益增多,視頻採集過程當中原始視頻分辨率起着愈來愈重要的做用,後續處理環節中使用的全部視頻分辨率的定義都以原始視頻分辨率爲基礎。視頻採集卡能支持的最大點陣反映了其分辨率的性能。

採樣頻率:採樣頻率反映了採集卡處理圖像的速度和能力。在進行高度圖像採集時,須要注意採集卡的採樣頻率是否知足要求。採樣率越高,圖像質量越高,同時保存這些圖像信息的數據量也越大。

採集介紹

  • AVFoundation: 音視頻數據採集須要用AVFoundation框架.

  • AVCaptureDevice:硬件設備,包括麥克風、攝像頭,經過該對象能夠設置物理設備的一些屬性(例如相機聚焦、白平衡等)

  • AVCaptureDeviceInput:硬件輸入對象,能夠根據AVCaptureDevice建立對應的AVCaptureDeviceInput對象,用於管理硬件輸入數據。

  • AVCaptureOutput:硬件輸出對象,用於接收各種輸出數據,一般使用對應的子類- 這裏是列表文本AVCaptureAudioDataOutput(聲音數據輸出對象)、AVCaptureVideoDataOutput(視頻數據輸出對象)

  • AVCaptionConnection:當把一個輸入和輸出添加到AVCaptureSession以後,AVCaptureSession就會在輸入、輸出設備之間創建鏈接,並且經過AVCaptureOutput能夠獲取這個鏈接對象。

  • AVCaptureVideoPreviewLayer:相機拍攝預覽圖層,能實時查看拍照或視頻錄製效果,建立該對象須要指定對應的AVCaptureSession對象,由於AVCaptureSession包含視頻輸入數據,有視頻數據才能展現。

  • AVCaptureSession: 協調輸入與輸出之間傳輸數據 系統做用:能夠操做硬件設備 工做原理:讓App與系統之間產生一個捕獲會話,至關於App與硬件設備有聯繫了, 咱們只須要把硬件輸入對象和輸出對象添加到會話中,會話就會自動把硬件輸入對象和輸出產生鏈接,這樣硬件輸入與輸出設備就能傳輸音視頻數據。

捕獲音視頻步驟

  • 一、建立AVCaptureSession對象。
  • 二、建立AVCaptureDevice對象來表示輸入設備, AVCaptureDevice對象只是用來調節硬件設備的配置。例如:攝像頭、麥克風。
  • 三、建立AVCaptureDeviceInput(音頻/視頻硬件輸入數據)對象,專門管理數據輸入。
  • 四、建立AVCaptureVideoDataOutput(音頻/視頻硬件輸出數據)對象,而且設置樣品緩存代理(setSampleBufferDelegate)就能夠經過它拿到採集到的視頻數據。
  • 五、將數據輸入對象AVCaptureDeviceInput、數據輸出對象AVCaptureOutput添加到媒體會話管理對象AVCaptureSession中,就會自動讓音頻輸入與輸出和視頻輸入與輸出產生鏈接。
  • 六、建立視頻預覽圖層AVCaptureVideoPreviewLayer並指定媒體會話,添加圖層到顯示容器layer中。
  • 七、啓動AVCaptureSession,只有開啓,纔會開始輸入到輸出數據流傳輸。

捕獲音視頻

// 捕獲音視頻
- (void)setupCaputureVideo
{
    // 1.建立捕獲會話,必需要強引用,不然會被釋放
    AVCaptureSession *captureSession = [[AVCaptureSession alloc] init];
    _captureSession = captureSession;

    // 2.獲取攝像頭設備,默認是後置攝像頭
    AVCaptureDevice *videoDevice = [self getVideoDevice:AVCaptureDevicePositionFront];

    // 3.獲取聲音設備
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];

    // 4.建立對應視頻設備輸入對象
    AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
    _currentVideoDeviceInput = videoDeviceInput;

    // 5.建立對應音頻設備輸入對象
    AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];

    // 6.添加到會話中
    // 注意「最好要判斷是否能添加輸入,會話不能添加空的
    // 6.1 添加視頻
    if ([captureSession canAddInput:videoDeviceInput]) {
        [captureSession addInput:videoDeviceInput];
    }
    // 6.2 添加音頻
    if ([captureSession canAddInput:audioDeviceInput]) {
        [captureSession addInput:audioDeviceInput];
    }

    // 7.獲取視頻數據輸出設備
    AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
    // 7.1 設置代理,捕獲視頻樣品數據
    // 注意:隊列必須是串行隊列,才能獲取到數據,並且不能爲空
    dispatch_queue_t videoQueue = dispatch_queue_create("Video Capture Queue", DISPATCH_QUEUE_SERIAL);
    [videoOutput setSampleBufferDelegate:self queue:videoQueue];
    if ([captureSession canAddOutput:videoOutput]) {
        [captureSession addOutput:videoOutput];
    }

    // 8.獲取音頻數據輸出設備
    AVCaptureAudioDataOutput *audioOutput = [[AVCaptureAudioDataOutput alloc] init];
    // 8.2 設置代理,捕獲視頻樣品數據
    // 注意:隊列必須是串行隊列,才能獲取到數據,並且不能爲空
    dispatch_queue_t audioQueue = dispatch_queue_create("Audio Capture Queue", DISPATCH_QUEUE_SERIAL);
    [audioOutput setSampleBufferDelegate:self queue:audioQueue];
    if ([captureSession canAddOutput:audioOutput]) {
        [captureSession addOutput:audioOutput];
    }

    // 9.獲取視頻輸入與輸出鏈接,用於分辨音視頻數據
    _videoConnection = [videoOutput connectionWithMediaType:AVMediaTypeVideo];

    // 10.添加視頻預覽圖層
    AVCaptureVideoPreviewLayer *previedLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
    previedLayer.frame = [UIScreen mainScreen].bounds;
    [self.view.layer insertSublayer:previedLayer atIndex:0];
    _previedLayer = previedLayer;

    // 11.啓動會話
    [captureSession startRunning];
}

// 指定攝像頭方向獲取攝像頭
- (AVCaptureDevice *)getVideoDevice:(AVCaptureDevicePosition)position
{
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if (device.position == position) {
            return device;
        }
    }
    return nil;
}

#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate
// 獲取輸入設備數據,有多是音頻有多是視頻
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    if (_videoConnection == connection) {
        NSLog(@"採集到視頻數據");
    } else {
        NSLog(@"採集到音頻數據");
    }
}

切換攝像頭

  • 一、獲取當前視頻設備輸入對象
  • 二、肯定切換攝像頭的方向
  • 三、根據攝像頭方向獲取對應的攝像頭設備
  • 四、建立對應的攝像頭輸入對象
  • 五、從會話中移除以前的視頻輸入對象
  • 六、添加新的視頻輸入對象到會話中
- (WXResult)switchCamera:(AVCaptureDevicePosition)position {
    
    // 獲取當前設備方向
    AVCaptureDevicePosition curPosition = wx_deviceInput.device.position;
    
    if (curPosition == position) {
        return WXResultNoErr;
    }
    // 建立設備輸入對象
    AVCaptureDevice *captureDevice = [AVCaptureDevice  defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:position];
    
    // 獲取改變的攝像頭輸入設備
    AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:nil];

    // 移除以前攝像頭輸入設備
    [wx_captureSession removeInput:wx_deviceInput];
    
    // 添加新的攝像頭輸入設備
    [wx_captureSession addInput:videoDeviceInput];
    
    // 記錄當前攝像頭輸入設備
    wx_deviceInput = videoDeviceInput;
    return WXResultNoErr;
}```

github 地址:
https://github.com/simonwxun/WXH264AndAACDemo.git
相關文章
相關標籤/搜索