gpt4 book ai didi

ios - 如何将应用程序音量与系统音量(iOS设备音量物理键)分开设置?

转载 作者:可可西里 更新时间:2023-11-01 06:22:47 30 4
gpt4 key购买 nike

我们的应用程序可以在wifi扬声器上播放音乐。该应用程序的功能之一是通过按音量+ /音量-iPhone上的硬键来更改扬声器的音量。

其背后的逻辑是获取系统的音量值并将其发送给扬声器。

但是,问题在于此功能会影响系统容量。无论如何,在应用程序内部按下音量键时,是否可以避免调节系统音量?

这是我每次按下都会获得系统音量的代码:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqual:@"outputVolume"])
{
CGFloat phoneVolume = [[AVAudioSession sharedInstance] outputVolume];
NSInteger volume = 100 * phoneVolume;

[self onHardKeyVolumeChange:volume];
}
}

谢谢。

最佳答案

这是我所做的:

  • 获取当前系统卷。
  • 隐藏音量调整弹出窗口。
  • 添加观察者以了解系统音量的变化。
  • 将系统卷设置回从观察者收到的每个回调中获得的卷(在步骤1)。

  • 我将详细解释每个步骤。

    步骤1-获取当前系统卷

    用于初始化卷的代码:
    - (void)initializeSystemVolume
    {
    _originalSystemVolume = [[AVAudioSession sharedInstance] outputVolume];
    _currentSystemVolume = _originalSystemVolume;

    if(_currentSystemVolume == 0.0)
    {
    _currentSystemVolume = 0.0625;
    }

    else if(_currentSystemVolume == 1.0)
    {
    _currentSystemVolume = 0.9375;
    }

    [self setSystemVolume:_currentSystemVolume];
    }

    _originalSystemVolume-这是进入应用程序时系统的容量。

    _currentSystemVolume-这也可以与原始卷 相同,但是可以更改,而originalSystemVolume应该保持不变。

    从if else语句可以看到,我将首先检查当前系统容量是最大值(1.0)还是最小值(0.0)。我为什么要这样做?

    因为从我的实验中,我注意到只有在系统音量已更改的情况下,才进行音量键的回调。因此,如果当前系统音量为最小值(0.0),而您仍按音量-按钮。不会进行回调。这样一来,您将永远无法确定音量-按键状态。

    因此,这就是为什么我需要在当前系统音量达到最小值时将其更改为较高的音量(0.0625),或者在其最大值处于最大音量时将其更改为较低的音量(0.9375),以便我们仍然能够获取回调从系统。现在,为什么是0.0625和0.9375?

    好吧,实际上我只想将其设置为最接近的可能值。
    如果您会注意到,iOS的音量分为16个级别,每个级别增加0.0625。 0.0是静音模式,而1.0是峰值音量。

    步骤2-隐藏音量调整弹出视图

    隐藏卷弹出窗口的代码:
    - (void)moveVolumeChangeNotifSliderOffTheScreen
    {
    CGRect frame = CGRectMake(0, -100, 10, 0);
    MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:frame];
    [volumeView sizeToFit];
    [[[[UIApplication sharedApplication] windows] objectAtIndex:0] addSubview:volumeView];
    }

    由于我们不会影响系统体积,因此也不应显示弹出窗口。

    此代码的功劳归于另一个人。对不起,我忘了我从哪里得到的,但我没有写。

    步骤3-添加观察者以观察系统音量的变化。

    现在,我们应该在每次按键时监听系统音量的变化,然后可以使用回调返回的值来确定按下哪个音量键。

    设置观察者的代码:
    - (void)setVolumeChangeObserver
    {
    [self removeVolumeChangeObserver];

    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    [[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:0 context:nil];
    }

    删除观察者的代码:
    - (void)removeVolumeChangeObserver
    {
    @try
    {
    [[AVAudioSession sharedInstance] removeObserver:self forKeyPath:@"outputVolume"];
    }

    @catch(id anException)
    {

    }
    }

    回调代码:
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    if ([keyPath isEqual:@"outputVolume"])
    {
    if([[AVAudioSession sharedInstance] outputVolume] < _currentSystemVolume)
    {
    NSLog(@"Volume key down");

    //your code when volume key down is pressed.
    }

    else if([[AVAudioSession sharedInstance] outputVolume] > _currentSystemVolume)
    {
    NSLog(@"Volume key up");

    //your code when volume key up is pressed.
    }

    [self removeVolumeChangeObserver];
    [self setSystemVolume:_currentSystemVolume];
    [self setVolumeChangeObserver];
    }
    }

    从代码中可以看出,我们在按下按键时使用了outputVolume并将其与我们之前设置的_currentSystemVolume进行比较,我们可以确定是否按下了volume +或按下了volume-。

    在分析了按下哪个键之后,我们应该立即将系统音量设置回原来的音量,这样在我们的应用程序中按下的音量键不会影响系统音量。

    重要:必须先删除观察者,然后再设置系统音量。为什么呢?因为如果您不这样做,则一旦设置系统音量,就会再次执行此回调,并且在发生这种情况时,将再次调用 setSystemVolume,然后再次进行回调,然后再次调用您的 setSystemVolume,然后一遍又一遍...您将为此创建一个死锁。通过删除观察者,将不会进行回调。

    步骤4-设置系统音量

    现在,我们如何设置系统音量呢?

    设置系统音量的代码:
    - (void)setSystemVolume:(CGFloat)volume
    {
    if(_volumeView == nil)
    {
    _volumeView = [[SystemVolumeView alloc] init];
    }

    _volumeView.getVolumeSlider.value = volume;
    }

    _volumeView是我创建的SystemVolumeView类的实例,该类扩展了MPVolumeView以检索MPVolumeView的UISlider。 MPVolumeView是您调整系统音量(媒体音量)时弹出的视图。

    SystemVolumeView的代码:

    SystemVolumeView.h
    #import <MediaPlayer/MediaPlayer.h>

    @interface SystemVolumeView : MPVolumeView

    - (UISlider *)getVolumeSlider;

    @end

    SystemVolumeView.m
    #import <AVFoundation/AVFoundation.h>

    #import "SystemVolumeView.h"

    @interface SystemVolumeView ()

    @property UISlider *systemVolumeSlider;

    @end

    @implementation SystemVolumeView

    - (UISlider *)getVolumeSlider
    {
    if(_systemVolumeSlider != nil)
    {
    return _systemVolumeSlider;
    }

    self.showsRouteButton = false;
    self.showsVolumeSlider = false;
    self.hidden = true;

    for(UIView *subview in self.subviews)
    {
    if([subview isKindOfClass:[UISlider class]])
    {
    _systemVolumeSlider = (UISlider *)subview;
    _systemVolumeSlider.continuous = true;

    return _systemVolumeSlider;
    }
    }

    return nil;
    }

    @end

    将此代码归功于 link中可接受的答案。我刚刚将其翻译为Objective-C。

    从上面的代码可以看出,您可以通过调用 getVolumeSlider.value = yourDesiredVolume来设置系统音量。 yourDesiredVolume的范围只能为0-1。

    好了,毕竟,您应该对它们的工作原理有所了解。

    现在,您可能会注意到我们没有使用 _originalSystemVolume

    这就是为什么。想象一下,如果系统的音量最初设置为静默,那么我们将其设置为更高的值以使一切正常工作吗?现在,一旦应用进入后台,我们应该将系统音量设置回原来的水平。在这种情况下,我们将在应用程序退出 Activity 时执行此操作。
    - (void)applicationWillResignActive:(UIApplication *)application
    {
    [self restoreSystemVolume];
    }

    恢复系统卷的代码:
    - (void)restoreSystemVolume
    {
    [self setSystemVolume:_originalSystemVolume];
    }

    那是所有人。希望这一答案对您有帮助。 :)

    感谢@Joris van Liempd iDeveloper。他的这份 link帮助我实现了这一目标。

    关于ios - 如何将应用程序音量与系统音量(iOS设备音量物理键)分开设置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36688123/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com