音频管理器(AudioManager)的低级别流类型有什么区别?

11

AudioManager中有几种流类型。它们在低级别上有何不同?例如,使用AudioManager.STREAM_MUSIC是否会阻塞输入麦克风流?或者还有其他什么原因吗?

3个回答

12

其中一个最显著的不同之处是音量控制。
文档所述,我们可以为每个流设置音量级别或调整音量。
我们还可以控制“音频焦点”,让其他应用停止播放或降低音量,以便在特定流上清晰地播放声音,否则声音将不会阻塞其他高优先级的声音,例如电话铃声、导航语音反馈等。

由于多个应用程序可能同时播放音频,因此重要的是考虑它们应该如何相互交互。为了避免所有音乐应用程序同时播放,Android使用音频焦点来调节音频播放-只有持有音频焦点的应用程序才能播放音频。

另一个未提到的事情是哪个音频设备会产生声音。
使用STREAM_MUSIC,声音将通过连接到手机的一个音频设备(手机扬声器、耳机、蓝牙音箱或其他设备)产生。
使用STREAM_RING,则声音将通过连接到手机的所有音频设备产生。 这种行为可能因设备而异。


@KeithYokoma。有没有可能通过其他流来减少流量?我观察到STREAM_VOICE_CALL正在降低STREAM_MUSIC的音量?你有什么猜测它是如何发生的吗? - Raghu Mudem

4

通常情况下,无法在Google文档中找到的内容(有时)可以从代码中理解。

https://android.googlesource.com/platform/frameworks/base/+/00ccd5d026fcd0e4b9d27dc5a9ffa13ca0408449/media/java/android/media/AudioService.java

至于阻塞,流之间并不会相互阻塞,只是模式会阻塞某些事物。MODE_IN_COMMUNICATION会阻塞大部分流。

降低音量: 播放长时间流(例如MUSIC)时的一种常见而“礼貌”的行为是侦听音频焦点回调,并在“can duck”事件发生时手动降低流的音量。当焦点返回到您的流时,音量应恢复到先前的水平。

流类型会影响流对所有声音总和的贡献音量:

   /** @hide Maximum volume index values for audio streams */
private int[] MAX_STREAM_VOLUME = new int[] {
    5,  // STREAM_VOICE_CALL
    7,  // STREAM_SYSTEM
    7,  // STREAM_RING
    15, // STREAM_MUSIC
    7,  // STREAM_ALARM
    7,  // STREAM_NOTIFICATION
    15, // STREAM_BLUETOOTH_SCO
    7,  // STREAM_SYSTEM_ENFORCED
    15, // STREAM_DTMF
    15  // STREAM_TTS

这个来自AudioService.java的数组展示了给定流的默认最大音量。其他代码:

    private void readPersistedSettings() {
    final ContentResolver cr = mContentResolver;
    mRingerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
    mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
    mRingerModeAffectedStreams = Settings.System.getInt(cr,
            Settings.System.MODE_RINGER_STREAMS_AFFECTED,
            ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
             (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
    mMuteAffectedStreams = System.getInt(cr,
            System.MUTE_STREAMS_AFFECTED,
            ((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
    mNotificationsUseRingVolume = System.getInt(cr,
            Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1);

似乎表明了当手机开始“响铃”或通话进行时哪些流被静音或降低音量。


当使用audiorecord并初始化audiotrack或另一个audiorecord时,您认为在任一audiotrack或audiorecord中选择错误的模式会使麦克风静音或无声禁用吗? - Kristian Martinsen
1
抱歉,我还没有对音频录制路径进行足够的实验。它很可能是相同的。不过,有些应用程序可以记录电话通话,有些应用程序可以随时显示声音水平,所以我想在麦克风方面更加灵活。麦克风是输入设备,所以我认为没有真正的冲突。同样的样本只需发送到应用程序A、B或C即可。也许会有音量等问题,但这只是一个小问题。 - Meymann
好的!我明白并理解逻辑。我会看一下通话录音器并进行调查!谢谢你的时间 :) - Kristian Martinsen
我在上面的答案中添加了一些代码片段,以展示使用不同流的一些效果(来自Meymann提到的代码)。 - Ribo

2
STREAM_ALARM        The audio stream for alarms
STREAM_DTMF         The audio stream for DTMF Tones
STREAM_MUSIC        The audio stream for music playback
STREAM_NOTIFICATION The audio stream for notifications
STREAM_RING         The audio stream for the phone ring
STREAM_SYSTEM       The audio stream for system sounds
STREAM_VOICE_CALL   The audio stream for phone calls

来自http://developer.android.com/reference/android/media/AudioManager.html

AudioManager类提供了访问音量和铃声模式的控制,以及控制各种音频路由的方法。它还包括用于通信、语音识别、音乐播放和其他类型的音频应用程序的API。


6
他们的作用非常明显。我的问题是它们在低级别下如何不同。它们不可能是10个完全相同的流。 - Kirill Boyarshinov
1
很明显你可以读取标识符的名称...每个流的行为是什么?哪个更优先?以什么音频模式播放?当哪个流播放时,哪个会被压低?哪个受到某些静音机制的影响? - Meymann

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