iOS编程修改系统音量
2016-02-16 11:31
363 查看
iOS的AVFoundation框架提供了基本的音视频播放工具,我们基本上可以靠其中提供的类完成绝大部分的音视频播放任务。但是在音频播放的输出音量的处理上,苹果的策略比较保守。尽管AVPlayer和AVPAudiolayerzhe这些类提供了音量调节功能,但这些音量控制属于App级别的控制。好处就是音量调节独立于系统音量,调节大小时不会影响系统音量。但有时候我们可能希望修改系统音量,以免在调节声音的时候,如果系统音量过小,App调节音量效果不明显。一般来说要调节系统音量会有以下方法:
请注意:修改系统音量无法在模拟器上看到效果,必须使用真机调试才能看到效果!
这个方法的缺点如下:
UI可定制的的程度低。 MPVolumeView只提供了有限的几个方法来定制其中的Slider和Route Button的样式,而且基本上只能靠换图片解决。如果你想把Slider操作换成Button或者其他的UI组件,那是不可能的。
没有额外的音量控制API。 目前为止没有发现iOS的公开API中有可以直接操作系统音量的,所以修改系统音量只能使用这个UI组件。
如果还想给UI加入手势操作来控制音量,这种直接使用MPVolumeView是做不到的,那么有没有什么方法可以绕过这限制呢?办法还是有的。
?
上面的代码演示如何获取和修改系统音量,注意音量取值为0到1之间的浮点数。
有时候这种提示我们未必会需要,那么怎么取消掉这个提示呢?实际上MPVolumeView没有提供任何接口来调节是否需要显示系统音量提示。但是我们发现一点:当MPVolumeView处在当前视图的层级之中时,系统就不会显示音量提示。那么事情好办了,我们只要确保两点:
MPVolumeView视图处在屏幕上看不见的地方,比如某个不透明视图的下方,或者本视图的非可见区域,一个常见的做法就是把该视图的frame设置为区域以外的地方,比如volumeView.frame = CGRectMake(-1000, -100, 100, 100);
确保MPVolumeView视图的hidden属性值为NO。因为当hidden为YES时,同样会弹出提示。
这里只需要监听AVSystemController_SystemVolumeDidChangeNotification事件即可。具体代码如下:
首先在资源载入阶段加入监听事件的代码
?
然后实现事件回调方法
?
最后记得在资源回收时取消掉事件监听
?
这样,每次用户使用硬件按钮调节音量的时候也会执行你写好的逻辑。
以上除了第一个方案以外,所有的解决方案都属于非官方的hack性质的方法,但是都没有调用私有API,所以没有被Apple审核拒掉的风险。
说法二:
在iOS设备中音量分为耳机音量和手机音量,二者相互独立:但是不管耳机还是 手机都是调用一种方法改变音量, 在设备上有耳机的时候改变耳机音量,没有耳机的时候改变手机音量。
在github中有一个开源项目:SystemVolumeNativeExtension . (点击获取链接)
在解压后找到 SystemVolumeNativeExtension/IOSVolumeLib/IOSVolumeLib/IOSVolumeLib.m 这个文件.
不用看太多,只需要关注:
&
如个你觉得这也有些繁琐: 那你直接使用:
newVolume的范围是 0 ~ 1;
简单说就是用这个即可设置耳机音量。
请注意:修改系统音量无法在模拟器上看到效果,必须使用真机调试才能看到效果!
使用MPVolumeView
这个方法是苹果官方推荐的方法。MPVolumeView是Media Player Framework中的一个UI组件,直接包含了对系统音量和Airplay设备的音频镜像路由的控制功能。其中包含一个MPVolumeSlider的subview用来控制音量。这个MPVolumeSlider是一个私有类,我们无法手动创建此类,但这个类是UISlider的子类。MPVolumeView的使用很简单,只需要将其加入到一个父视图中,给予父视图合适的大小,再创建MPVolumeView示例,将其加入到父视图中即可,苹果官方的文档1中有示例代码可以参考。这个方法的缺点如下:
UI可定制的的程度低。 MPVolumeView只提供了有限的几个方法来定制其中的Slider和Route Button的样式,而且基本上只能靠换图片解决。如果你想把Slider操作换成Button或者其他的UI组件,那是不可能的。
没有额外的音量控制API。 目前为止没有发现iOS的公开API中有可以直接操作系统音量的,所以修改系统音量只能使用这个UI组件。
如果还想给UI加入手势操作来控制音量,这种直接使用MPVolumeView是做不到的,那么有没有什么方法可以绕过这限制呢?办法还是有的。
编程实现系统音量调节
上一小节我们提到了MPVolumeView这个组件中,有一个subview来控制音量,即MPVolumeSlider。其实我们可以通过遍历MPVolumeView实例的subviews来得到MPVolumeSlider的实例,从而通过这个UI组件来操作系统音量。通过MPVolumeSlider的实例来操作系统音量
我们首先通过创建一个MPVolumeView,然后遍历找出MPVolumeSlider的实例。这个实例提供setValue:animated:方法来设置系统音量。我们也可以通过volumeSlider.value这个属性来获取当前的系统音量。具体的代码如下:?
有问题!我不喜欢系统弹出音量提示
上面通过编程的方法可以很完美的调节系统音量,但是每次修改都会弹出系统提示框告知:有时候这种提示我们未必会需要,那么怎么取消掉这个提示呢?实际上MPVolumeView没有提供任何接口来调节是否需要显示系统音量提示。但是我们发现一点:当MPVolumeView处在当前视图的层级之中时,系统就不会显示音量提示。那么事情好办了,我们只要确保两点:
MPVolumeView视图处在屏幕上看不见的地方,比如某个不透明视图的下方,或者本视图的非可见区域,一个常见的做法就是把该视图的frame设置为区域以外的地方,比如volumeView.frame = CGRectMake(-1000, -100, 100, 100);
确保MPVolumeView视图的hidden属性值为NO。因为当hidden为YES时,同样会弹出提示。
还有问题,我修改了系统音量但是不是通过我的UI
另一个可能的情况就是用户自己通过硬件的音量调节按钮(位于设备侧边)来调节音量,这种情况会使得你的业务逻辑出现问题,因为你只为自己的App UI写了回调,那么怎么为硬件按钮的事件添加回调呢?我们可以使用Notification Center来完成。这里只需要监听AVSystemController_SystemVolumeDidChangeNotification事件即可。具体代码如下:
首先在资源载入阶段加入监听事件的代码
?
?
?
以上除了第一个方案以外,所有的解决方案都属于非官方的hack性质的方法,但是都没有调用私有API,所以没有被Apple审核拒掉的风险。
说法二:
在iOS设备中音量分为耳机音量和手机音量,二者相互独立:但是不管耳机还是 手机都是调用一种方法改变音量, 在设备上有耳机的时候改变耳机音量,没有耳机的时候改变手机音量。
在github中有一个开源项目:SystemVolumeNativeExtension . (点击获取链接)
在解压后找到 SystemVolumeNativeExtension/IOSVolumeLib/IOSVolumeLib/IOSVolumeLib.m 这个文件.
不用看太多,只需要关注:
float getVolumeLevel() { MPVolumeView *slide = [MPVolumeView new]; UISlider *volumeViewSlider; for (UIView *view in [slide subviews]) { if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) { volumeViewSlider = (UISlider *) view; } } float val = [volumeViewSlider value]; [slide release]; return val; }
&
FREObject setVolume(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) { double newVolume; FREGetObjectAsDouble(argv[0], &newVolume); [[MPMusicPlayerController applicationMusicPlayer] setVolume: newVolume]; return NULL; }
如个你觉得这也有些繁琐: 那你直接使用:
[[MPMusicPlayerController applicationMusicPlayer] setVolume: newVolume];
newVolume的范围是 0 ~ 1;
简单说就是用这个即可设置耳机音量。
相关文章推荐
- iOS中屏幕适配问题
- IOS xcode 删除git使用svn
- iOS开发证书都显示“此证书的签发者无效”,更新WWDR Certificate证书后还是显示无效
- iOS9获取系统语言改变了
- IOS 开发 证书显示 此证书签发者无效 解决办法
- ios 发布应用程序
- iOS 给label加下划线或者中划线
- Xcode 7 error: “Missing iOS Distribution signing identity for …”
- iOS SVN--Cornerstone
- 【Flash ANE iOS】关于Flash ANE在iOS上面遇到的一些问题
- iOS 保持界面流畅的技巧
- iOS实现三屏复用循环广告[从服务器请求的广告]
- 个推推送iOS版 常见问题详解
- ios 中的session使用以及nsstring中方法的使用
- iOS开发中“此证书的签发者无效”的解决方案
- 关于苹果开发证书失效的解决方案(2016年2月14日Failed to locate or generate matching signing assets)
- iOS内存管理和malloc源码解读
- iOS开发-相关书籍整理
- Missing iOS Distribution signing identity问题解决
- ios7 view被导航栏遮挡问题的解决