需求場景
新進(jìn)一個(gè)錄音界面欲间,在進(jìn)入錄音界面的時(shí)候代乃,將系統(tǒng)的音量強(qiáng)制設(shè)置成0.1,并隱藏系統(tǒng)自帶的音量彈框提示醇王,取而代之的是類似抖音視頻播放界面底層的音量進(jìn)度條呢燥,離開該錄音界面的時(shí)候,將系統(tǒng)的聲音恢復(fù)到進(jìn)入之前的音量寓娩,且在恢復(fù)的時(shí)候不彈出系統(tǒng)音量提示框叛氨。
下面會(huì)分以下幾個(gè)步驟來記錄一下。
<1>首先需要知道如何隱藏系統(tǒng)自帶的音量彈框提示棘伴?
在iOS中寞埠,有直接設(shè)置音量大小的系統(tǒng)API
[MPMusicPlayerController applicationMusicPlayer].volume = 0.1;
還有一個(gè)與用戶交互的音量設(shè)置界面(MPVolumeView)
_volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(0,-1000, UIScreen.mainScreen.bounds.size.width, 2)];
在iOS7之后,蘋果不建議使用直接設(shè)置音量大小的API焊夸,而是使用MPVolumeView來控制音量的大小仁连。這樣做的原因是防止惡意軟件對聲音的控制影響了用戶的體驗(yàn)。但是阱穗,該API還是可以用的饭冬。
回到重點(diǎn),在使用API控制系統(tǒng)音量的時(shí)候揪阶,會(huì)出現(xiàn)系統(tǒng)的音量的彈框(出現(xiàn)在正中間的那個(gè))伍伤。那么怎樣才能讓他消失了?實(shí)踐證明遣钳,在MPVolumeView對象屬于當(dāng)前顯示的視圖的子視圖的情況下扰魂,使用API調(diào)節(jié)音量大小的時(shí)候,系統(tǒng)音量的彈框是不會(huì)出現(xiàn)的蕴茴。此時(shí)劝评,你會(huì)發(fā)現(xiàn)MPVolumeView對象的進(jìn)度條會(huì)發(fā)生變化。這表明了MPVolumeView對象替代了系統(tǒng)音量彈框的存在倦淀。到這蒋畜,隱藏系統(tǒng)音量彈框的需求也就解決了。
<2>如何保存進(jìn)入錄音界面之前的系統(tǒng)音量撞叽?
這里我們先獲取進(jìn)入之前的系統(tǒng)音量姻成,然后保存起來插龄。那么如何獲取系統(tǒng)音量了?這里我們使用
self.lastSystemVolume = [AVAudioSession sharedInstance].outputVolume;
為什么不使用?[MPMusicPlayerController applicationMusicPlayer].volume?來獲取系統(tǒng)音量了科展?
注意:這里有個(gè)坑均牢,以?[MPMusicPlayerController applicationMusicPlayer].volume?的方式來獲取系統(tǒng)的音量的時(shí)候,有的時(shí)候會(huì)返回0才睹。所以保險(xiǎn)起見徘跪,還是使用[AVAudioSession sharedInstance].outputVolume.
<3>如何在進(jìn)入錄音界面之后設(shè)置新的系統(tǒng)音量?
在上面已經(jīng)寫道如何設(shè)置新的系統(tǒng)音量琅攘,代碼如下:
[MPMusicPlayerController applicationMusicPlayer].volume = 0.1;
<4>如何監(jiān)聽音量的變化?
這是重點(diǎn)垮庐,監(jiān)聽系統(tǒng)音量的方式有兩種。
第一種是監(jiān)聽系統(tǒng)通知:AVSystemController_SystemVolumeDidChangeNotification坞琴,這也是最方便的哨查;
第二種是使用KVO進(jìn)行監(jiān)聽,代碼如下剧辐;
[[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:(void *)[AVAudioSession sharedInstance]];
這里的outputVolume解恰,也就我們上面用來獲取系統(tǒng)音量大小屬性。
在此浙于,以第一種的方式來監(jiān)聽,監(jiān)聽代碼如下:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
方法實(shí)現(xiàn)代碼如下:
- (void)volumeChanged:(NSNotification*)notification
{
? ? dispatch_async(dispatch_get_global_queue(0, 0), ^{
? ? ? ? if ([self.volumeViewEventStatus isEqualToString:VolumeViewEventViewWillDisappear] || [self.volumeViewEventStatus isEqualToString:VolumeViewEventViewDidAppear]) {
? ? ? ? ? ? self.volumeViewEventStatus = @"";
? ? ? ? ? ? return;
? ? ? ? };
? ? ? ? NSDictionary*userInfo = notification.userInfo;
? ? ? ? NSString *reasonStr = userInfo[@"AVSystemController_AudioVolumeChangeReasonNotificationParameter"];
? ? ? ? if(![reasonStrisEqualToString:@"ExplicitVolumeChange"])return;
? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{
? ? ? ? ? ? if(self.volumeView.frame.origin.y!=300)
? ? ? ? ? ? ? ? self.volumeView.frame = CGRectMake(0, 300, UIScreen.mainScreen.bounds.size.width, 2);
? ? ? ? ? ? [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hiddenVolumeView) object:nil];
? ? ? ? ? ? [selfperformSelector:@selector(hiddenVolumeView)withObject:nilafterDelay:1];
? ? ? ? });
? ? });
}
- (void)hiddenVolumeView{
? ? if (self.volumeView.frame.origin.y != -1000) dispatch_async(dispatch_get_main_queue(), ^{
? ? ? ? self.volumeView.frame = CGRectMake(0, -1000, UIScreen.mainScreen.bounds.size.width, 2);
? ? });
}
在方法volumeChanged中挟纱,入?yún)?b>notification.userInfo的詳情如下
{
? ? "AVSystemController_AudioCategoryNotificationParameter" = "Audio/Video";
? ? "AVSystemController_AudioVolumeChangeReasonNotificationParameter" = ExplicitVolumeChange;
? ? "AVSystemController_AudioVolumeNotificationParameter" = "0.1000000014901161";
? ? "AVSystemController_UserVolumeAboveEUVolumeLimitNotificationParameter" = 0;
}
其中AVSystemController_AudioVolumeChangeReasonNotificationParameter是觸發(fā)該通知理由羞酗,這個(gè)理由有好幾種,比如ExplicitVolumeChange(系統(tǒng)音量發(fā)生了變化)紊服,RouteChange(一般發(fā)生在錄音的時(shí)候檀轨,使用了其他的通道)等。
<5>如何在離開錄音界面之后恢復(fù)之前的系統(tǒng)音量?
同<3>
具體的代碼可以查閱Demo欺嗤,僅供參考参萄。歡迎討論。