国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

iOS錄音和播放的那些事兒:幾個奇葩的需求

2019-11-06 09:45:29
字體:
來源:轉載
供稿:網友

轉自:http://www.2cto.com/kf/201501/373159.html

最近在做的項目中,需要在iphone上接上帶麥耳機(蘋果叫Headset,不帶麥耳機叫Headphone),然后實現同步錄音和播放。這個功能實現之后,需要改變錄音、播放的輸入源。

對于實現同步錄音和播放功能,肯定就要使用到底層的接口,用AVAudioRecorder/AVAudioPlayer是無法實現的。

我研究了iOS聲音處理的知識之后,發現自己實現太過麻煩,需要用到至少包括AudioQueue/AudioBuffer等等,然后還有各種復雜的C Struct、回調函數、回調處理等等,非常麻煩,一不小心就出錯,很難找到出錯的地方。于是我在網上找了一個比較著名的封閉好的庫,Novocaine。它對聲音的輸入、輸出都實現的比較好,也提供了很簡單明確的回調函數,我只要修改一下回調函數就可以了,這里不表。

后面項目需要確定能否實現一種輸入/輸出方式:在插入帶麥克風的耳機時,能夠讓聲音從耳機麥克風輸入,然后同步的從手機內置揚聲器播放。

在手機插入帶麥耳機后,輸入源共有2個:內置麥克風(Build-In Microphone)、耳機麥克風(Wired Microphone);輸出源有3個:打電話時用的,在上面的那個輸出(Built-In Receiver)、耳機(Wired Headphones)和放音樂時用的內置揚聲器(Built-In Speaker)。

查了蘋果的文檔后發現,根據蘋果的產品策略,用戶在插入帶麥耳機后,會自動將輸入源切換到耳機麥克風,將輸出源切換到耳機。而且,在輸入源是耳機麥克風的時候,將輸出源切換到耳機是強制的。這句話比較繞,我舉個例子。假如現在輸入源是耳機麥克風,那么輸入源只能是耳機。而如果將輸入源切換到手機內置麥克風(這是可以實現的)的時候,則可以將輸出源切換到手機。

蘋果認為,插入耳機代表用戶只想從耳機聽聲音。為了保護用戶的隱私,蘋果不允許開發者隨便換輸出源。也就是說,雖然蘋果提供了3種方法用于切換輸出源(都比較繁瑣,后面可能會再寫一篇博客),但在用戶插入耳機,并且我們需要輸入源是耳機麥克風的情況下,是無法將輸出源切換到內置揚聲器的。這里有更詳細的說明:http://stackoverflow.com/questions/5931799/redirecting-audio-output-to-phone-speaker-and-mic-input-to-headphones

第二個問題是,需要在耳機插入的狀態下,將輸入源調整為手機內置麥克風,而輸出源仍然保持為耳機。

在千能(不是萬能)的AVAudiosession類里,提供了幾個很好的方法:

打印當前正在工作的輸入/輸入源:

?
1234NSArray* input = [[AVAudioSession sharedInstance] currentRoute].inputs;NSArray* output = [[AVAudioSession sharedInstance] currentRoute].outputs;NSLog(@"current intput:%@",input);NSLog(@"current output:%@",output);
打印現在可用的輸入源:

?
12NSArray* availableInputs = [[AVAudioSession sharedInstance] availableInputs];NSLog(@"available inputs:%@",availableInputs);

AVAudioSession沒有提供可用的輸出源的列表。

將耳機插入之后,打印可用的輸入源,結果如下:

?
12345672015-01-2617:45:40.747PRegNotice[605:6d13] available inputs:( "", "" )</avaudiosessionportdescription:></avaudiosessionportdescription:>
可以看出,現在可用的輸入源包括內置麥克風和耳機麥克風(Wired Microphone)。我們通過以下方法改變輸入源:

?
1234567NSArray* inputArray = [[AVAudioSession sharedInstance] availableInputs];for(AVAudioSessionPortDescription* desc in inputArray) {    if([desc.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {        NSError* error;        [[AVAudioSession sharedInstance] setPreferredInput:desc error:&error];    }}
同樣,在需要切換回來時,檢查desc.portType是不是AVAudioSessionPortHeadsetMic,如果是,調整回來。

需要注意的是,使用這個方法會觸發AVAudioSessionRouteChangeNotification通知,而插入耳機后,也會調用這個通知。我在測試的時候,為了檢查耳機插入的動作,監聽了這個通知,然后在通知回調方法里通過上面方法修改了輸入源,導致又觸發了通知,所以插入1次耳機導致了2次調用。

關于聲音,AVAudioSession,還有很多需要了解的。有興趣的同學,需要搞定iOS聲音的同學,一定要好好學學。


上一篇:iOS 面試題

下一篇:IOS 打包上架

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 衡阳县| 大庆市| 台山市| 雷波县| 靖宇县| 南投市| 山西省| 平远县| 井研县| 兴安盟| 固始县| 三门峡市| 务川| 汶上县| 西宁市| 龙门县| 东宁县| 宁南县| 蒙山县| 汾阳市| 个旧市| 勐海县| 大石桥市| 文昌市| 泸水县| 略阳县| 巩留县| 海宁市| 准格尔旗| 涟源市| 横山县| 曲阜市| 苏尼特左旗| 冀州市| 天峻县| 申扎县| 大洼县| 江永县| 娄烦县| 梁平县| 宁晋县|