You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过代码将Chromecast投屏的音频通道切换至蓝牙耳机?

Chromecast投屏状态下切换音频到蓝牙耳机的解决方案

嘿,我懂你现在的困扰——常规的AudioManager操作在Chromecast投屏时完全不管用,因为这时音频流已经被系统路由到Cast设备上了。别担心,咱们用Android的MediaRouter API就能搞定这个问题,下面是具体的步骤和代码:

核心思路

Chromecast投屏时,系统会把媒体(音频/视频)的输出路由到Cast设备,所以要先把媒体路由切回本地设备,再用你原来的蓝牙切换逻辑来接管音频输出。

具体实现步骤

1. 获取MediaRouter实例

首先要拿到系统的MediaRouter,它是管理所有媒体路由状态的核心类:

val mediaRouter = applicationContext.getSystemService(Context.MEDIA_ROUTER_SERVICE) as MediaRouter

2. 检测当前是否处于Chromecast投屏状态

通过MediaRouter的选中路由,判断当前是否在投屏:

val isCasting = mediaRouter.selectedRoute.type == MediaRouter.RouteType.LIVE_AUDIO || 
                mediaRouter.selectedRoute.type == MediaRouter.RouteType.LIVE_VIDEO

3. 切换回本地路由并切换蓝牙音频

如果当前在投屏,先把路由切回本地,再执行你原来的蓝牙切换逻辑:

fun switchAudioToBluetoothWhileCasting() {
    val mediaRouter = applicationContext.getSystemService(Context.MEDIA_ROUTER_SERVICE) as MediaRouter
    val localRoute = mediaRouter.getDefaultRoute()
    
    // 如果当前在投屏,先切回本地路由
    if (mediaRouter.selectedRoute != localRoute) {
        mediaRouter.selectRoute(localRoute)
        // 等待路由切换完成(简单用延迟,也可以用回调监听更可靠)
        Handler(Looper.getMainLooper()).postDelayed({
            // 执行你原来的蓝牙切换逻辑(对应你代码里切换到蓝牙的分支)
            audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
            audioManager.isBluetoothScoOn = true
            audioManager.startBluetoothSco()
            audioManager.isSpeakerphoneOn = false
            initButtonSettingLayout()
        }, 500)
    } else {
        // 不在投屏时,直接用你原来的逻辑即可
        if (!bluetoothSound) {
            audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
            audioManager.isBluetoothScoOn = true
            audioManager.startBluetoothSco()
            audioManager.isSpeakerphoneOn = false
            initButtonSettingLayout()
        }
    }
}

4. 用回调监听路由切换(更可靠的方式)

如果不想用延迟,可以注册MediaRouter.Callback监听路由切换完成事件,避免因设备性能差异导致的逻辑执行时机错误:

val routerCallback = object : MediaRouter.Callback() {
    override fun onRouteSelected(router: MediaRouter, type: Int, route: MediaRouter.RouteInfo) {
        super.onRouteSelected(router, type, route)
        // 确认路由切回本地后,执行蓝牙切换
        if (route == router.getDefaultRoute()) {
            audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
            audioManager.isBluetoothScoOn = true
            audioManager.startBluetoothSco()
            audioManager.isSpeakerphoneOn = false
            initButtonSettingLayout()
            // 记得注销回调,避免内存泄漏
            mediaRouter.unregisterCallback(this)
        }
    }
}

// 注册回调并触发路由切换
mediaRouter.registerCallback(routerCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY)
mediaRouter.selectRoute(localRoute)

注意事项

  • 确保你的应用已申请必要权限:Android 12及以上需要BLUETOOTH_CONNECT,同时要有ACCESS_NETWORK_STATE权限来检测Cast设备状态。
  • 如果想保持投屏视频但单独把音频转到蓝牙,这种场景非常复杂——因为Chromecast的音视频输出是绑定的,常规API无法拆分,需要自定义Cast接收端,成本很高,一般建议还是先切回本地再用蓝牙播放。

内容的提问来源于stack exchange,提问作者Vincent Chann

火山引擎 最新活动