如何在 iPhone 应用程序中设置硬件音量?

发布于 2024-07-07 16:44:36 字数 173 浏览 6 评论 0原文

一些iPhone应用程序,例如Pandora,似乎直接操纵硬件音量并响应物理音量按钮。 这是怎么做到的?

AudioSessionServices 允许您使用 kAudioSessionProperty_CurrentHardwareOutputVolume 属性获取当前硬件输出音量,但它(据称)是只读的。

Some iPhone applications, such as Pandora seem to directly manipulate the hardware volume and respond to physical volume button. How is this done?

AudioSessionServices allows you to get the current hardware output volume with the kAudioSessionProperty_CurrentHardwareOutputVolume property, but it is (allegedly) read-only.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

彩虹直至黑白 2024-07-14 16:44:36

他们使用 MPVolumeView,简单地添加它,当用户触摸它时,它就完成了其余的工作。 注意:在 iPhone 模拟器中不起作用。 我认为发行说明还提到不要直接在 Interface Builder 中使用它。

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(25, 378, 270, 30)];
[self.view addSubview:volumeView];
[volumeView release];

They use the MPVolumeView, simple add it and it's makes the rest when the user touch it. Note: Doesn't work in iPhone Simulator. I think the release note also mentioned do not use it direct in Interface Builder.

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(25, 378, 270, 30)];
[self.view addSubview:volumeView];
[volumeView release];
奈何桥上唱咆哮 2024-07-14 16:44:36

这是设置硬件音量并在按下硬件键后检索音量的另一个(完整)示例:

// AVAudiosession Delegate Method
- (void)endInterruptionWithFlags:(NSUInteger)flags
{
    // When interruption ends - set the apps audio session active again
    [[AVAudioSession sharedInstance] setActive:YES error:nil];

    if( flags == AVAudioSessionInterruptionFlags_ShouldResume ) {
        // Resume playback of song here!!!
    }
}

// Hardware Button Volume Callback
void audioVolumeChangeListenerCallback (
                                         void                      *inUserData,
                                         AudioSessionPropertyID    inID,
                                         UInt32                    inDataSize,
                                         const void                *inData)
{
    UISlider * volumeSlider = (__bridge UISlider *) inUserData;
    Float32 newGain = *(Float32 *)inData;
    [volumeSlider setValue:newGain animated:YES];
}

// My UISlider Did Change Callback
- (IBAction)volChanged:(id)sender
{
    CGFloat oldVolume = [[MPMusicPlayerController applicationMusicPlayer] volume];
    CGFloat newVolume = ((UISlider*)sender).value;

    // Don't change the volume EVERYTIME but in discrete steps. 
    // Performance will say "THANK YOU"
    if( fabsf(newVolume - oldVolume) > 0.05 || newVolume == 0 || newVolume == 1  )
        [[MPMusicPlayerController applicationMusicPlayer] setVolume:newVolume];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Set the volume slider to the correct value on appearance of the view 
    volSlider.value = [[MPMusicPlayerController applicationMusicPlayer] volume];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    // Activate the session and set teh delegate
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    [[AVAudioSession sharedInstance] setDelegate:self];

    // Create a customizable slider and add it to the view
    volSlider = [[UISlider alloc] init];
    CGRect sliderRect = volSlider.frame;
    sliderRect.origin.y = 50;
    sliderRect.size.width = self.view.bounds.size.width;
    volSlider.frame = sliderRect;
    [volSlider addTarget:self action:@selector(volChanged:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:volSlider];

    // Regoister the callback to receive notifications from the hardware buttons
    AudioSessionAddPropertyListener (
                                                                 kAudioSessionProperty_CurrentHardwareOutputVolume ,
                                                                 audioVolumeChangeListenerCallback,
                                                                 (__bridge void*)volSlider
                                                                 );

    [...]
}

- (void)viewDidUnload
{
    [super viewDidUnload];

    // Remove the Hardware-Button-Listener
    AudioSessionRemovePropertyListenerWithUserData(
            kAudioSessionProperty_CurrentHardwareOutputVolume, 
            audioVolumeChangeListenerCallback, 
            (__bridge void*)volSlider);
}

Here is another (complete) example of setting the hardware volume AND retrieving the volume after pressing the hardware keys:

// AVAudiosession Delegate Method
- (void)endInterruptionWithFlags:(NSUInteger)flags
{
    // When interruption ends - set the apps audio session active again
    [[AVAudioSession sharedInstance] setActive:YES error:nil];

    if( flags == AVAudioSessionInterruptionFlags_ShouldResume ) {
        // Resume playback of song here!!!
    }
}

// Hardware Button Volume Callback
void audioVolumeChangeListenerCallback (
                                         void                      *inUserData,
                                         AudioSessionPropertyID    inID,
                                         UInt32                    inDataSize,
                                         const void                *inData)
{
    UISlider * volumeSlider = (__bridge UISlider *) inUserData;
    Float32 newGain = *(Float32 *)inData;
    [volumeSlider setValue:newGain animated:YES];
}

// My UISlider Did Change Callback
- (IBAction)volChanged:(id)sender
{
    CGFloat oldVolume = [[MPMusicPlayerController applicationMusicPlayer] volume];
    CGFloat newVolume = ((UISlider*)sender).value;

    // Don't change the volume EVERYTIME but in discrete steps. 
    // Performance will say "THANK YOU"
    if( fabsf(newVolume - oldVolume) > 0.05 || newVolume == 0 || newVolume == 1  )
        [[MPMusicPlayerController applicationMusicPlayer] setVolume:newVolume];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Set the volume slider to the correct value on appearance of the view 
    volSlider.value = [[MPMusicPlayerController applicationMusicPlayer] volume];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    // Activate the session and set teh delegate
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
    [[AVAudioSession sharedInstance] setDelegate:self];

    // Create a customizable slider and add it to the view
    volSlider = [[UISlider alloc] init];
    CGRect sliderRect = volSlider.frame;
    sliderRect.origin.y = 50;
    sliderRect.size.width = self.view.bounds.size.width;
    volSlider.frame = sliderRect;
    [volSlider addTarget:self action:@selector(volChanged:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:volSlider];

    // Regoister the callback to receive notifications from the hardware buttons
    AudioSessionAddPropertyListener (
                                                                 kAudioSessionProperty_CurrentHardwareOutputVolume ,
                                                                 audioVolumeChangeListenerCallback,
                                                                 (__bridge void*)volSlider
                                                                 );

    [...]
}

- (void)viewDidUnload
{
    [super viewDidUnload];

    // Remove the Hardware-Button-Listener
    AudioSessionRemovePropertyListenerWithUserData(
            kAudioSessionProperty_CurrentHardwareOutputVolume, 
            audioVolumeChangeListenerCallback, 
            (__bridge void*)volSlider);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文