模块一 一.系统(铃声)音量,媒体音量,通话音量,静音键 (此处暂不提各软件的音量,下面讨论不涉及软件音量,因为各软件涉及到调用的问题,请看第四项) 1. 定义: 系统音量,指的是带有铃声的声音(设置-声音里面的所有提醒声音,包括闹钟,但闹钟比较特殊请看第二项)。具体为来电铃声,通知铃声,闹铃等。 媒体音量,iOS常指音乐,视频,主动播放类声音。包含部分软件内的声音等。 通话音量,当你通话,facetime时,调节音量键,即可调整通话音量。 以上三类音量,是相对独立控制的,不可交互调节。而且都会自动记忆调节量。 2. 特殊的是系统音量与媒体音量(关键在于:设置-声音-<用按钮调整>开关) 实例: 【关闭<用按钮调整>】:主屏幕调节音量键,显示的是音量(此处是指媒体音量),而系统(铃声)音量则必须在[设置-声音]中用控制条调节。 【打开<用按钮调整>】:主屏幕调节音量键,显示的是铃声(此处是指系统(铃声)音量,只能调到最低一格),而不是调节媒体音量,则媒体音量必须在主动播放类(音乐,视频,部分软件)之中调节音量键。所以有时候你明明一直按着音量减,打开程序的时候却还是很大声就是这个原因。 所以很迷糊,很绕是吧,没关系,关闭<用按钮调节>按钮,单独控制好系统铃声音量,想静音就直接拨静音键。主屏幕或锁屏调节音量键就是调节媒体音量(包括大部分软件音量) 3. 静音键不管什么? 静音键管的东西可多了(包括拍照声,嘿嘿**记得静音啊!!!),但是我们最好心里清楚它到底不管什么!防止拨开静音键却某些声音不被静音! 静音键不管闹钟,通话音量,媒体音量,所以拨了静音键放动作片或者高潮音乐时,你会被行注目礼的。 其他的静音键都管! 二.闹钟 闹钟响还是不响?这是最大的问题了吧! 闹钟调用的是系统(铃声)音量,但是闹钟是系统音量中唯一不受静音键控制的!却受制于<设置-音量>中的音量控制条! 所以<用按钮调整>这一开关尤为重要! 实例分析一下, 【打开<用按钮调整>】:当你在待机界面按音量键调低音量后,系统铃声就会随着减小,太小就会漏接电话,更有甚者会闹钟、提醒听不到耽误大事啊! 【关闭<用按钮调整>】:将设置-音量-音量控制条调节适当,不论在哪调节音量键都不会改变闹钟和铃声的音量大小,闹铃会很安全的。 注意,iPhone以前和现在都不支持关机闹铃!千万不要养成睡觉关机的“好习惯”(BTW:以前不支持关机充电,现在支持关机充电) 三.耳机音量与手机外放 1. 耳机音量控制最简便,不论什么声音,例如铃声什么的,都会平衡成你当前调节的耳机音量,不用担心被突如其来的铃声撕裂耳膜。 2. 非静音时当有系统提醒时,耳机会响,手机外放也会响,其他声音只走耳机。 静音时,系统提醒耳机不会响,手机也不会响。但你听音乐、看视频、玩游戏的声音还是会走耳机传出来。 一句话,插上耳机,打开静音按钮,手机就绝对不会出声音了。关闭静音按钮,只有系统提醒会走手机放出,其他声音一律不会走手机。放心用你的耳机!(你懂的,就算播放某视频或音乐,意外拔出耳机,也不会泄露声音,视频或音乐会自动暂停。) 四.各软件音量!(最难搞的地方) 软件分很多类型,游戏,音乐,阅读等等一堆。它们调用的到底是系统音量还是媒体音量呢?很不好判断,所以有时候静音键也不一定都管用。 例如:XX音乐软件,它肯定调用媒体音量啊!不对!它的一部分可能是调用媒体音量!软件内播放视频音乐,是调用媒体音量!软件内新消息提醒有可能调用系统(铃声)音量! 所以如果想弄懂,很麻烦,要一个一个软件自己去习惯和尝试了。 上面这句是废话,下面这些才是关键: (手机外放)彻底静音一个的方法: 1. 【关闭<用按钮调整>】,打开静音键,主屏幕或锁定屏幕调低音量至静音即可! 2. 【打开<用按钮调整>】,打开静音键,先播放音乐然后把音量调低至静音(或直接上拉控制中心,调低音量控制条)即可! 3. 插入耳机,打开静音键!(只有耳机会有声音哦) 赶着下班,差不多写完了,也没怎么检查,如有问题我再跟大家探讨,下一次写什么大家来决定吧! 最近项目有个功能需要用到监听音量实体键,并能够通过滑动应用内的UISlider调整系统的音量,其中遇到不少问题,所以记录下这个学习过程。 尽管 AVPlayer 和 AVPAudiolayer 这些类提供了音量调节功能,但这些音量控制属于App级别的控制。好处就是音量调节独立于系统音量,调节大小时不会影响系统音量。但有时候我们可能希望修改系统音量,以免在调节声音的时候,如果系统音量过小,App调节音量效果不明显。 模块二 一、监听手机实体音量按键
- (void)registeNotification{ //1.注册监听系统音量变化,记得在适当的地方移除监听 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; //让 UIApplication 开始响应远程的控制,必须添加,不然没效果 [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; } - (void)volumeChanged:(NSNotification *)notification{ //2.获取到当前音量 float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue]; //do something here } - (void) removeNotification{ //3.移除监听 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; } //结束远程的控制 [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; 虽然有效果,但是问题来了 1.实体键按下的时候,会出现系统的"铃声",而我想要显示"音量" 这个时候可以添加一句代码,即可让在这个页面时,按下音量实体键显示 音量 ,而不是铃声 //使音量控制实体键响应“音量”而不是”铃声” [[AVAudioSession sharedInstance] setActive:YES error:NULL]; 2.出现了"音量",但是因锁屏、进入后台等原因 ResignActive 重新激活后,又显示了"铃声"而不是"音量" 这是因为程序进入后台后,上述一行代码 [AVAudioSession sharedInstance] 又不再是 Active 状态,所以需要在 AppDelegate.m 里面重新设置,这样即可一直响应“音量”了,比如: AppDelegate.m - (void)applicationWillEnterForeground:(UIApplication *)application { //使程序重新激活后,对音量实体键响应为“音量”而不是“铃声” [[AVAudioSession sharedInstance] setActive:YES error:NULL]; } 3.我不想出现"音量" 这个时候就需要用到 MPVolumeView 了,它不仅可以不显示“音量”,还可以修改设置手机音量。 这个方法是苹果官方推荐的方法。MPVolumeView是 Media Player Framework 中的一个UI组件,直接包含了对系统音量和Airplay设备的音频镜像路由的控制功能。其中包含一个 MPVolumeSlider 的subview用来控制音量。这个 MPVolumeSlider 是一个私有类,我们无法手动创建此类,但这个类是UISlider的子类。MPVolumeView的使用很简单,只需要将其加入到一个父视图中,给予父视图合适的大小,再创建 MPVolumeView 示例,将其加入到父视图中即可, 苹果官方的文档 中有示例代码可以参考。
于是想要隐藏"音量提示框"就可以通过添加以下代码实现: //隐藏"音量提示框" //注意使用之前需要添加`MediaPlayer.framework` MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, -100, 100, 100)]; volumeView.hidden = NO; [self.view addSubview:volumeView]; 代码实现调节系统音量,不通过实体按键 上面我们提到了MPVolumeView这个组件中,有一个subview来控制音量,即 MPVolumeSlider 。于是我们可以通过遍历 MPVolumeView 实例的subviews来得到MPVolumeSlider的实例,从而通过这个UI组件来操作系统音量。
具体的代码如下: - (void)viewDidLoad { [super viewDidLoad]; //不显示“铃声”,显示“音量” [[AVAudioSession sharedInstance] setActive:YES error:NULL]; //1. 获得 MPVolumeView 实例, MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-100, -100, 100, 100)]; //volumeView.hidden = NO; //[self.view addSubview:volumeView]; //添加后不显示“音量” volumeViewSlider = nil; //2. 遍历MPVolumeView的subViews得到MPVolumeSlider for (UIView *view in [volumeView subviews]){ if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ volumeViewSlider = (UISlider*)view; break; } } //3.获取系统音量 float systemVolume = volumeViewSlider.value; //4.添加一个全局的 slider,滑动时同步改变系统音量 VolSlider = [[UISlider alloc] initWithFrame:CGRectMake(30, 200, 300, 20)]; VolSlider.value = systemVolume; //初始值 [VolSlider setMinimumValue:0.0]; //最小值 [VolSlider setMaximumValue:1.0]; //最大值 [VolSlider addTarget:self action:@selector(sliderValueChange:) forControlEvents:UIControlEventValueChanged]; //添加事件 [self.view addSubview:VolSlider]; //注册监听实体键按下事件 [self registeNotification]; } // //VolSlider滑动事件 - (void)sliderValueChange:(UISlider *)slider{ //得到当前用户设置的value float value = slider.value; //改变系统音量大小,默认音量大小从 0.0 - 1.0 [volumeViewSlider setValue:value animated:NO]; //使setValue立即生效, [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside]; } // //监听音量实体键按下后,响应事件 - (void)volumeChanged:(NSNotification *)notification{ //获取到当前系统音量 float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue]; //同步设置自定义视图的值 [VolSlider setValue:volume animated:YES]; } 设置后即可使 VolSlider 与系统的音量提示框同步了,效果如下: 模块三方法1: 在applicationDidFinishLaunching函数里添加 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil]; - (void)volumeChanged:(NSNotification *)notification { float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
DDLogVerbose(@"current volume = %f", volume); } 弊端:当app进入后天后,依然会监听到volume的变化 2. 对 AudioSession 添加volume变化的 listener, 可以放在startAudioSession函数里 //add a listener for Outputvolume AudioSessionAddPropertyListener(kAudioSessionProperty_CurrentHardwareOutputVolume , volumeListenerCallback, self ); void volumeListenerCallback ( void *inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData ){ const float *volumePointer = inData; float volume = *volumePointer; NSLog(@"volumeListenerCallback %f", volume); } 3. 获取当前的volume float volume = 0.0; UInt32 dataSize = sizeof(float); OSStatus status = AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareOutputVolume, &dataSize, &volume); |
版权所有,禁止匿名转载;禁止商业使用。