iOS: Airplay选择器MPVolumeView替代方案

4
我正在使用MPVolumeView选择用于AVPlayer Airplay播放的Airplay设备。 是否有任何可能的非私有API替代方法来完成此操作,以便我可以提供自己的UI控件来选择Airplay设备?
通过参考API,我的意思是,我只需要以下内容:
1.能够将音频重定向到特定的Airplay设备音频路由。 2.检索Airplay设备名称。(获取所有可用的音频路由,然后获取Airplay音频路由的描述)
我知道AudioToolbox框架提供了一些额外的API来处理AudioSession,但我发现重定向音频的唯一方法是使用AVAudioSession的:
- (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride  error:(NSError **)outError`

该功能仅允许将音频重定向到内置扬声器。也许还有其他方法可以实现这个功能吗?(我只找到了通过当前音频路由的描述来获取Airplay设备名称的方法 - 使用AVPlayer获取AirPlay设备的名称

2个回答

6

所以对于我的问题,精确的答案如下:

(i) 除了切换到内置扬声器外,使用公共API在程序中无法自动切换音频路线。

[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];

(ii) 仅当它是活动的AudioRoute时,您才能检索一个Airplay设备的名称。 通过AVPlayer获取AirPlay设备名称

因此,提供自定义UI控件以选择Airplay的实用解决方案是:

定制MPVolumeView,您可以在其中禁用volumeSlider并自定义routeButton。但是,您不得不在UIActionSheet中从适用于苹果设备的无线设备列表(如AirPlay、蓝牙等)中选择Airplay设备,这将弹出当您点击routeButton时。但是,您可以通过订阅audioRouteChangeNotification来观察用户何时会进行选择。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteHasChangedNotification:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];

请注意,如果您插入/拔出耳机,也会触发此通知。
如果您想了解如何使用私有API检索所有可用的音频路由并进行编程切换:
"MPMediaPlayer"框架包含一个名为"MPAVRoutingController"的私有类,它可以让您做到这一点:
Class MPAVRoutingController = NSClassFromString(@"MPAVRoutingController");
Class MPAVRoute = NSClassFromString(@"MPAVRoute");

id routingController = [[MPAVRoutingController alloc] init];
NSArray* availableRoutes = [routingController performSelector:@selector(availableRoutes)];
BOOL isSwitchSuccesful = [[routingController performSelector:@selector(pickRoute:) withObject:availableRoutes.lastObject] boolValue];

(如果您想要访问音频路由信息并检查是否为Airplay:检测Airplay路由

我曾经有一个类似的问题,想知道是否可以在不使用私有API的情况下实现普通的操作表,而无需进行自定义? - Roberto Andrade
我不知道他们是否向其中添加了任何新的API,但似乎我们无法直接使用他们的ActionSheet(现在称为AlertController)进行任何操作。你可以尝试玩一下 - 比如尝试访问它的视图子视图并尝试使用sendActionsForControlEvents来查看是否可以编程模拟用户触摸,如果可以,那么你可能可以通过编程方式切换路由而不需要使用私有API。 - ambientlight
你可以检查一下MPAVRoutingController在iOS 11.3.1上是否还能工作,对我来说它已经不能用了。 - Jas_meet

1

应该使用 AVRoutePickerView 来管理所有音频输出。

例如,可以创建以下子类:

final class AMRoutePickerView: AVRoutePickerView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        translatesAutoresizingMaskIntoConstraints = false
        tintColor = .clear
        activeTintColor = .clear
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

通过设置.clear,我们隐藏了该视图的可视内容。 现在,可以将此视图作为可触摸UI的任何视图或按钮的顶部子视图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接