如何在Airplay处于活动状态时自定义Airplay按钮 [英] How to customize the Airplay button when airplay is active

查看:429
本文介绍了如何在Airplay处于活动状态时自定义Airplay按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在试图解决这个问题2天,我放弃了。我试图实现一个定制的airplay按钮(我必须beacuse的背景是白色的,按钮必须是黑色的)。 Ive在interfacebuilder中添加了一个视图,并为它选择了mpVolumeView。然后我做了连接并写下面的代码;

Been trying to solve this issue for 2 days now and I give up. Im trying to implement a customized airplay button (I have to beacuse the background is white and the button must be black). Ive added a view in interfacebuilder and chose mpVolumeView for it. Then I made the connections and wrote the following code;

viewDidLoad.. {
    .....

    [_volumeView setShowsVolumeSlider:NO];
    for (UIButton *button in _volumeView.subviews) {
        if ([button isKindOfClass:[UIButton class]]) {
            [button setImage:[UIImage imageNamed:@"airplay_icon.png"] forState:UIControlStateNormal];
            [button addObserver:self forKeyPath:@"alpha" options:NSKeyValueObservingOptionNew context:nil];
            [button addTarget:self action:@selector(switchAirplayButton) forControlEvents:UIControlEventTouchUpInside];
            [button sizeToFit];
        }
    }
    [_volumeView sizeToFit];

}

-(void)switchAirplayButton {

    for (UIButton *button in _volumeView.subviews) {
        if ([button isKindOfClass:[UIButton class]]) {

            NSLog(@"%d", _controlBar.player.airPlayVideoActive);

            if(_controlBar.player.airPlayVideoActive) {
                [button setImage:[UIImage imageNamed:@"airplay_icon_pressed.png"] forState:UIControlStateNormal];
            } else  [button setImage:[UIImage imageNamed:@"airplay_icon.png"] forState:UIControlStateNormal];

            [button sizeToFit];
        }
    }


}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([object isKindOfClass:[UIButton class]] && [[change valueForKey:NSKeyValueChangeNewKey] intValue] == 1) {
        [(UIButton *)object setImage:[UIImage imageNamed:@"airplay_icon.png"] forState:UIControlStateNormal];
        [(UIButton *)object sizeToFit];
    }
}

播放器是基于AVPLayer的singelton。但是,当检查airPlay是否活动时,它总是返回false。也许它只是beacuse im使用声音,而不是视频。

The "player" is a singelton based on AVPLayer. However, it always returns false when checking if airPlay is active. Maybe it's just beacuse im using sound, not video.

所以我的问题是,我怎么改变按钮...让我们说一个橙色的(只是为了匹配接口的其余部分)airplay是流就像苹果是蓝色的)。我试过一切,它只是不工作。请帮帮我。

So my question is, how could I change the button to... lets say an orange one (just to match the rest of the interface) when airplay is streaming (just like apple is making it blue). I have tried everything and it's just not working at all. Please help me.

推荐答案

编辑:

虽然下面的代码适用于iOS 5和6,从iOS 6.0开始,有一个官方的方式做到这一点,这是容易得多。只需查看 MPVolumeView 的文档,特别是 - setRouteButtonImage:forState:

Though the code below works on both iOS 5 and 6, starting with iOS 6.0 there is an official way to do this, which is much much easier. Just look at the documentation of MPVolumeView, specifically – setRouteButtonImage:forState:.

====老回答:====

==== Old answer: ====

这很难完成,但我发现了一个iOS 5.0+的方法。首先,将以下行添加到您的ViewController:

This is pretty hard to accomplish, but I found a way for iOS 5.0+. First of all, add the following line to your ViewController:

#import <AudioToolbox/AudioToolbox.h>



在你的viewDidLoad中,你已经做了大部分的事情,这是我的代码: / p>

In your viewDidLoad, you're already doing most of the things right, this is my code:

for (id current in self.volumeView.subviews){
    if([current isKindOfClass:[UIButton class]]) {
        UIButton *airPlayButton = (UIButton*)current;
        self.airPlayButton = airPlayButton;
        [self setAirPlayButtonSelected:[self isAirPlayActive]];
        [airPlayButton addObserver:self forKeyPath:@"alpha" options:NSKeyValueObservingOptionNew context:nil];
    }
}

这里是帮助 setAirPlayButtonSelected 方法,它只是设置图像:

Here's the helper setAirPlayButtonSelected method, it just sets the image:

- (void)setAirPlayButtonSelected:(BOOL)selected {
    UIImage* image;
    if (selected) {
        image = [UIImage imageNamed:@"button-airplay-selected"];
    }else {
        image = [UIImage imageNamed:@"button-airplay"];
    }
    [self.airPlayButton setImage:image forState:UIControlStateNormal];
    [self.airPlayButton setImage:image forState:UIControlStateHighlighted];
    [self.airPlayButton setImage:image forState:UIControlStateSelected];
}

为了完成, observeValueForKeyPath

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if (object == self.airPlayButton && [[change valueForKey:NSKeyValueChangeNewKey] intValue] == 1) {
        [self setAirPlayButtonSelected:[self isAirPlayActive]];
    }
}

现在有趣的部分。这是 isAirPlayActive 帮助方法。它使用AudioSession框架来确定当前正在播放的audioSource。

And now comes the interesting part. Here's the isAirPlayActive helper method. It uses the AudioSession framework to determine the currently playing audioSource.

- (BOOL)isAirPlayActive{
    CFDictionaryRef currentRouteDescriptionDictionary = nil;
    UInt32 dataSize = sizeof(currentRouteDescriptionDictionary);
    AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, &currentRouteDescriptionDictionary);
    if (currentRouteDescriptionDictionary) {
        CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs);
        if(CFArrayGetCount(outputs) > 0) {
            CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0);
            CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type);
            return (CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo);
        }
    }

    return NO;
}

因此,所有这些代码都会在应用启动时正确更改AirPlay按钮。如何更新?我们需要监听AudioSource的变化。将以下行添加到您的 viewDidLoad

So all this code changes the AirPlay Button correctly on app launch. What about updates? We need to listen for AudioSource changes. Add the following line to your viewDidLoad:

    AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, audioRouteChangeCallback, (__bridge void*)self);

不要忘记取消注册 dealloc

- (void)dealloc {
    [self.airPlayButton removeObserver:self forKeyPath:@"alpha"];

    AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeCallback, (__bridge void*)self);

}

将此C函数添加到ViewController的 @implementation

And add this C function above your ViewController's @implementation:

void audioRouteChangeCallback (void                   *inUserData,
                                       AudioSessionPropertyID inPropertyID,
                                       UInt32                 inPropertyValueSize,
                                       const void             *inPropertyValue) {

    if (inPropertyID != kAudioSessionProperty_AudioRouteChange) {
        return;
    }

    CFDictionaryRef routeChangeDictionary = inPropertyValue;

    CFDictionaryRef currentRouteDescriptionDictionary = CFDictionaryGetValue(routeChangeDictionary, kAudioSession_AudioRouteChangeKey_CurrentRouteDescription);
    CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs);
    if(CFArrayGetCount(outputs) > 0) {
        CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0);
        CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type);

        [(__bridge SettingsViewController*)inUserData setAirPlayButtonSelected:CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo];
    }

}

确定AirPlay输出源是否活动,并相应地调用 setAirPlayButtonSelected 方法。

As you can see, all it does is determine whether or not an AirPlay output source is active and calls the setAirPlayButtonSelected method accordingly.

a href =http://developer.apple.com/library/ios/#documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Introduction/Introduction.html>音频会话编程指南,特别是本部分有关回调如何正确工作的详细信息等。

See Apple's Audio Session Programming Guide, specifically this section for detailed information on how the callbacks exactly work, etc.

这篇关于如何在Airplay处于活动状态时自定义Airplay按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆