實現iOS 耳返的功能能夠經過AudioUnit來進行實現。node
實現的步驟以下:web
建立AudioSession
獲取硬件的權限objective-c
在iOS的音視頻開發中,使用音頻回話須要建立一個AudioSession,用於管理與獲取iOS設備的音頻信息。session
AVAudioSession *session = [AVAudioSession sharedInstance];
根據咱們的具體需求來設置類別:svg
1)在類別中若是須要進行錄音等操做,須要設置類別爲record 類型函數
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:&error];
2)設置I/O 的buffer,buffer越小說明延遲越低post
NSTimeInterval bufferTimer = 0.01; [session setPreferredIOBufferDuration:bufferTimer error:nil];
3) 進行audioSession
被打斷進行監聽code
/// 接收session 被打斷的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]]; /// 處理監聽 - (void)handleInterruption:(NSNotification *)notification { NSDictionary *dic = notification.userInfo; if ([notification.userInfo[AVAudioSessionInterruptionTypeKey] intValue] == AVAudioSessionInterruptionTypeBegan) { // 開始被打斷,暫停 } else if ([dic[AVAudioSessionInterruptionTypeKey] intValue] == AVAudioSessionInterruptionTypeEnded) { // 結束打斷了, 重開 }
}component
構建AudioUnit視頻
在建立並啓用音頻會話以後,就能夠構建AudioUnit 了。構建的時候須要制定類型、子類型以及廠商。咱們以RemoteIO 這個AudioUnit爲例來說解他的參設置,RemoteIO 這個AudioUnit 是一個和硬件相關的Unit,他分爲輸入端和輸出端。輸入端通常指的就是麥克風,輸出端指的就是揚聲器或者耳機。若是同時須要輸入輸出,即咱們的耳返功能,則須要開發者作一些設置將他們聯繫起來。
AudioUnit
的屬性AUGraph
對象(表明 audio processing graph)。(能夠經過其餘方式建立audioUnit)AUNode
對象(每個表明一個 audio unit in the graph.)。AudioComponentDescription audioDesc = {0}; audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple; audioDesc.componentType = kAudioUnitType_Output; audioDesc.componentSubType = kAudioUnitSubType_RemoteIO; audioDesc.componentFlags = 0; audioDesc.componentFlagsMask = 0; // 建立augraph AUGraph processingGraph; NewAUGraph(&processingGraph); // 按照描述在AUGraph 中增長一個AUNode AUNode ioNode; AUGraphAddNode(processingGraph, &audioDesc, &ioNode); // 打開AUGraph AUGraphOpen(processingGraph); // 得到audioUnit 的引用 AudioUnit audioUnit; AUGraphNodeInfo(processingGraph, ioNode, NULL, &audioUnit);
// 配置屬性 UInt32 oneFlag = 1; AudioUnitSetProperty(remoteIOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &oneFlag, sizeof(oneFlag)); AudioUnitSetProperty(remoteIOUnit, // unit kAudioOutputUnitProperty_EnableIO, // ID kAudioUnitScope_Input, // scope 0, // element &oneFlag, sizeof(oneFlag));
3. 使用`AUGraphSetNodeInputCallback` 配置audioUnit回調函數 ```Objc inputProc.inputProc = myInputCallBack; inputProc.inputProcRefCon = (__bridge void *)(self); AUGraphSetNodeInputCallback(auGraph, remoteIONode, 0, &inputProc)
4.使用audioGraph爲audioUnit 分配內存
// 在調用initialize 以前能夠先調用update 方法,若是update 成功,則graph 已經被動態配置就位 AUGraphUpdate(auGraph, NULL); AUGraphInitialize(auGraph);
AUGraphStart(auGraph); // cashow 是打印狀態 CAShow(auGraph);
AUGraphStop(auGraph);