【问题标题】:iOS: Airplay picker MPVolumeView alternativeiOS:Airplay 选择器 MPVolumeView 替代品
【发布时间】:2014-04-11 08:36:32
【问题描述】:

我正在使用 MPVolumeView 来选择用于 avplayer 播放的播放设备。 是否有任何可能的非私有 API 替代方法来执行此操作,以便我能够提供自己的 UI 控件来选择播放设备?

提到 API,我的意思是,我所需要的只是:

  1. 能够将音频重新路由到播放设备特定的 audioRoute。
  2. 检索播放设备名称。 (获取所有可用的 audioRoutes,然后获取 airplay audioRoutes 的描述)

我知道 AudioToolbox 框架提供了一些额外的 API 来处理 AudioSession,但我发现重新路由音频的唯一方法是 AVAudioSession:

- (BOOL)overrideOutputAudioPort:(AVAudioSessionPortOverride)portOverride  error:(NSError **)outError`

只允许将音频重新路由到内置扬声器。也许还有其他方法可以在那里实现它? (我也只找到了如何检索 AirplayDevice 的名称作为 currentAudioRoute 的描述的方法 - Get name of AirPlay device using AVPlayer

【问题讨论】:

    标签: ios airplay audiotoolbox


    【解决方案1】:

    所以我的问题的确切答案:

    (i) 除了切换到内置扬声器外,无法使用公共 API 以编程方式切换 audioRoutes。

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

    (ii) 只有在激活 AudioRoute 的情况下才能检索 airplay-device 的名称。 Get name of AirPlay device using AVPlayer

    因此,呈现自定义 UI 控件以选择播放的实用解决方案是:

    要自定义MPVolumeView,您可以在此处禁用volumeSlider并自定义routeButton。但是,您没有其他选择可以在UIActionSheet 中的苹果兼容无线设备(airPlay、蓝牙等)列表中选择 airplayDevice,当您点击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];
    

    (如果你想访问audioRoute信息并检查它是否是Airplay:Detecting airplayRoute

    【讨论】:

    • 我有一个 similar question,想知道如果不使用私有 API,即使是没有自定义的常规操作表也可以实现?
    • 我不知道他们是否确实向其中添加了任何新的 API,但似乎我们无法直接对他们的 ActionSheet(现在它称为 AlertController)做任何事情。您可以尝试使用它 - 比如尝试访问其视图子视图并尝试 sendActionsForControlEvents 以查看您是否可以通过编程方式伪造用户触摸,如果可以,那么您可能会在没有私有 API 的情况下以编程方式切换路由
    • 你能检查 MPAVRoutingController 是否仍在 iOS 11.3.1 中工作,对我来说它不再工作了。
    【解决方案2】:

    应该使用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 中任何视图或按钮的顶部子视图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      相关资源
      最近更新 更多