我使用亚马逊的 AWS Chime 建立 voip 音频通信。我的实际设置有点复杂,我将chime android sdk构建到一个模块中,并进行了一些更改以删除视频部分,并将其包含在我基于 Unity 的 Oculus Quest 2 应用程序中。不过,我也测试了 Chime 的演示应用,通过 Android Studio 直接将 APK 发送到 Quest 2;它运行并正确连接到会议、流式音频甚至聊天。
不幸的是,使用硬件按钮更改音量没有任何效果。
我将以下代码段添加到演示应用程序中,用于测试目的
val audioManager = getContext()?.getSystemService(AUDIO_SERVICE) as AudioManager
Log.d("1234", "audiomanager mode " + audioManager.mode);
val observer: ContentObserver = object : ContentObserver(Handler(Looper.myLooper())) {
override fun onChange(selfChange: Boolean, uri: Uri?) {
super.onChange(selfChange, uri)
val audioManager = getContext()?.getSystemService(AUDIO_SERVICE) as AudioManager
Log.d("1234", "new ONCHANGE system settings " + uri.toString() + " current mode " + audioManager!!.mode)
Log.d("1234", "ONCHANGE stream MUSIC current " + audioManager!!.getStreamVolume(AudioManager.STREAM_MUSIC))
Log.d("1234", "ONCHANGE stream VOICe CALL current " + audioManager!!.getStreamVolume(AudioManager.STREAM_VOICE_CALL))
Log.d("1234", "ONCHANGE stream STREAM_ACCESSIBILITY current " + audioManager!!.getStreamVolume(AudioManager.STREAM_ACCESSIBILITY))
Log.d("1234", "ONCHANGE stream STREAM_ALARM current " + audioManager!!.getStreamVolume(AudioManager.STREAM_ALARM))
Log.d("1234", "ONCHANGE stream STREAM_DTMF current " + audioManager!!.getStreamVolume(AudioManager.STREAM_DTMF))
Log.d("1234", "ONCHANGE stream STREAM_NOTIFICATION current " + audioManager!!.getStreamVolume(AudioManager.STREAM_NOTIFICATION))
Log.d("1234", "ONCHANGE stream STREAM_RING current " + audioManager!!.getStreamVolume(AudioManager.STREAM_RING))
Log.d("1234", "ONCHANGE stream STREAM_SYSTEM current " + audioManager!!.getStreamVolume(AudioManager.STREAM_SYSTEM))
}
}
getContext()?.getContentResolver()?.registerContentObserver(Settings.System.CONTENT_URI, true, observer)
首先,在 Quest 上,每次更改都发生在 uricontent://settings/system/volume_music_speaker
上,连接时Audiomanage.getMode()
从 0 到 3 的更改MODE_IN_COMMUNICATION
。
在最近的 Oculus 软件更新后,一个音频流上的每一个更改都会自动应用到所有其他音频流。这就是为什么如果我按两次硬件音量按钮,这就是我的日志显示的原因
D/1234: new ONCHANGE system settings content://settings/system/volume_music_speaker current mode 3
D/1234: ONCHANGE stream MUSIC current 6
D/1234: ONCHANGE stream VOICe CALL current 3
D/1234: ONCHANGE stream STREAM_ACCESSIBILITY current 7
D/1234: ONCHANGE stream STREAM_ALARM current 3
D/1234: ONCHANGE stream STREAM_DTMF current 6
D/1234: ONCHANGE stream STREAM_NOTIFICATION current 3
D/1234: ONCHANGE stream STREAM_RING current 3
D/1234: ONCHANGE stream STREAM_SYSTEM current 3
D/1234: new ONCHANGE system settings content://settings/system/volume_music_speaker current mode 3
D/1234: ONCHANGE stream MUSIC current 5
D/1234: ONCHANGE stream VOICe CALL current 2
D/1234: ONCHANGE stream STREAM_ACCESSIBILITY current 6
D/1234: ONCHANGE stream STREAM_ALARM current 3
D/1234: ONCHANGE stream STREAM_DTMF current 5
D/1234: ONCHANGE stream STREAM_NOTIFICATION current 2
D/1234: ONCHANGE stream STREAM_RING current 2
D/1234: ONCHANGE stream STREAM_SYSTEM current 2
显示所有流的值都发生了变化(每个流都相对于它们自己的最大/最小值。例如从 1 到 5 的 CALL 等)
问题是即使我到达这种情况
D/1234: new ONCHANGE system settings content://settings/system/volume_music_speaker current mode 3
D/1234: ONCHANGE stream MUSIC current 0
D/1234: ONCHANGE stream VOICe CALL current 1
D/1234: ONCHANGE stream STREAM_ACCESSIBILITY current 1
D/1234: ONCHANGE stream STREAM_ALARM current 1
D/1234: ONCHANGE stream STREAM_DTMF current 0
D/1234: ONCHANGE stream STREAM_NOTIFICATION current 0
D/1234: ONCHANGE stream STREAM_RING current 0
D/1234: ONCHANGE stream STREAM_SYSTEM current 0
与我交谈的人的实际音量没有下降。
Chime 的主 sdk 依赖于开发人员发布的预编译辅助 sdk,其代码不公开。我对其进行了反编译,JD GUI
但其中包含实际内容的方法受到保护。我只能在他们的 webrtc 库中看到, anAudioTrack
被实例化并用于流式传输语音字节,并且它设置为AudioSessioId
0 。AudioManager
将模式设置为 3,仅此而已(可见)。如果我有对 AudioTrack 的引用,我可以尝试直接更改音量,但它不会暴露。
我试过了:
- 反编译媒体 sdk 以查看发生了什么,但它受到保护。
NotificationListenerService
通过注册为 a并调用来寻找正在进行的 AudioSessionsMediaSessionManager#getActiveSessions
,但不存在来自 chime 的会话(确实出现了后台的 spotify,所以我的代码有效)- 做
AudioManager.setMode(0)
,但即使模式改变,音量仍然没有下降。 - 附加
audiofx.Equalizer
到会话 0(已弃用)只是为了看看我是否可以改变所有频段的增益并降低全局输出组合的音量。但它对会话 0 没有影响。(我仔细检查了将 eq 应用于测试 AudioTrack 和测试 MediaPlayer 的代码,它在两种情况下都有效) - 考虑使用 NDK 来访问 AudioFlinger,但它确实看起来很复杂而且矫枉过正。
- 在 Chime 的 github repo 上写了一个问题,因为我正在寻找答案,所以很难得到答案,而且该应用程序是为 Android 设计的,音量确实会改变
- 编写一个测试 android 应用程序,在其中我在流模式下创建了一个 AudioTrack,将其属性设置为
USAGE_VOICE_COMMUNICATION
andCONTENT_TYPE_SPEECH
,将 AudioManager 的模式更改为 3 并通过 Android Studio 在 Oculus Quest 上运行它。通过按下硬件音量按钮和以编程方式正确更改了音频。因此,它一定是 chime hidden media sdk 所做的与 Quest 的 Android 不兼容的事情。
最终,我不明白的是,第三方 webrtc 库如何能够在 MODE_IN_COMMUNICATION 中播放 AudioTrack,即使我以编程方式降低每个流的音量,例如AudioManager.STREAM_MUSIC
,AudioManager.STREAM_VOICE_CALL
等,实际音量不会改变而getStreamVolume()
另有说法。而且,怎么可能允许第三方库播放音频,而开发人员无法访问所有播放内容并控制它们。
我希望在 Android 音频和 Oculus Quest 内部恶作剧方面比我更有经验的人能够对正在发生的事情有所了解。