日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

ttplayer綠色版 ttsplayer( 三 )


//需要錄音時,AudioSession的設置代碼如下:if ([AVAudioSession sharedInstance].category != AVAudioSessionCategoryPlayAndRecord) {[RTCAudioSessionCacheManager cacheCurrentAudioSession];AVAudioSessionCategoryOptions categoryOptions = AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionMixWithOthers;if (@available(iOS 10.0, *)) {categoryOptions |= AVAudioSessionCategoryOptionAllowBluetooth;}[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:categoryOptions error:nil];[[AVAudioSession sharedInstance] setActive:YES error:nil];}//功能結(jié)束時重置audioSession[RTCAudioSessionCacheManager resetToCachedAudioSession];static AVAudioSessionCategory cachedCategory = nil;static AVAudioSessionCategoryOptions cachedCategoryOptions = nil;@implementation RTCAudioSessionCacheManager//更改audioSession前緩存RTC當下的設置+ (void)cacheCurrentAudioSession {if (![[AVAudioSession sharedInstance].category isEqualToString:AVAudioSessionCategoryPlayback] && ![[AVAudioSession sharedInstance].category isEqualToString:AVAudioSessionCategoryPlayAndRecord]) {return;}@synchronized (self) {cachedCategory = [AVAudioSession sharedInstance].category;cachedCategoryOptions = [AVAudioSession sharedInstance].categoryOptions;}}//重置到緩存的audioSession設置+ (void)resetToCachedAudioSession {if (!cachedCategory || !cachedCategoryOptions) {return;}BOOL needResetAudioSession = ![[AVAudioSession sharedInstance].category isEqualToString:cachedCategory] || [AVAudioSession sharedInstance].categoryOptions != cachedCategoryOptions;if (needResetAudioSession) {dispatch_async(dispatch_get_global_queue(0, 0), ^{[[AVAudioSession sharedInstance] setCategory:cachedCategory withOptions:cachedCategoryOptions error:nil];[[AVAudioSession sharedInstance] setActive:YES error:nil];@synchronized (self) {cachedCategory = nil;cachedCategoryOptions = nil;}});}}@end兜底策略考慮到在線教室場景的復雜度,讓教室內(nèi)所有功能代碼都遵循 AVAudioSession 的修改規(guī)范 , 雖然有嚴格的 codeReview,但是也存在一定的人為因素風險,隨著業(yè)務功能不斷迭代 , 無法完全保證線上不出問題,因此一套可靠的兜底策略顯得非常有必要 。
兜底策略的基本邏輯是 hook 到 AVAudioSession 的變化,當各模塊對 AVAudioSession 的設置不符合規(guī)范要求時,我們在不影響功能的前提下強制進行修正,比如對 options 補充上混音模式 。
通過方法交換我們可以 hook 到 AVAudioSession 的更改 。比如用 kk_setCategory:withOptions: error: 與系統(tǒng)的 setCategory:withOptions: error: 進行交換,在交換的方法里,我們判斷 options 是否包含 AVAudioSessionCategoryOptionMixWithOthers,如果沒有包含我們就進行追加 。
- (BOOL)kk_setCategory:(AVAudioSessionCategory)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError {//在需要進行對audioSession進行修正的場景下(RTC直播),修改options時未包含mixWithOther , 則給options追加mixWithOtherBOOL addMixWithOthersEnable = shouldFixAudioSession && !(options & AVAudioSessionCategoryOptionMixWithOthers)];if (addMixWithOthersEnable) {return [self kk_setCategory:category withOptions:options | AVAudioSessionCategoryOptionMixWithOthers error:outError];;}return [self kk_setCategory:category withOptions:options error:outError];}但上述方法只對通過調(diào)用 setCategory:withOptions: error: 來設置 AVAudioSession 有效,如果某個模塊調(diào)用 setCategory:error: 方法來設置 AVAudioSession,setCategory:error: 方法默認會將options設置為 0(未包含AVAudioSessionCategoryOptionMixWithOthers) 。我們 hook 到 setCategory:error: 方法后 , 無法通過調(diào)整參數(shù)的方式來為options追加混音模式選項,但是可以在交換的方法內(nèi)改為調(diào)用 setCategory:withOptions:error: 方法,并將 options 參數(shù)傳入AVAudioSessionCategoryOptionMixWithOthers , 來滿足我們的需求 ??蓡栴}在于調(diào)用 setCategory:withOptions:error: 時,底層會再嵌套調(diào)用 setCategory:error: 方法,而此時setCategory:error: 已經(jīng)被我們hook并且在交換的方法內(nèi)調(diào)用了setCategory:withOptions:error: , 如此便形成了死循環(huán) 。

推薦閱讀