【问题标题】:What is the difference between AudioManager's stream types at low level?AudioManager 在底层的流类型有什么区别?
【发布时间】:2014-08-30 10:10:18
【问题描述】:

AudioManager 中有几种流类型。它们在低层次上有何不同?会不会是例如的用法? AudioManager.STREAM_MUSIC 阻止输入麦克风流?还是别的什么?

【问题讨论】:

    标签: android android-audiomanager


    【解决方案1】:

    一个最显着的区别是音量控制。
    正如document 所说,我们可以分别为每个流设置音量级别或调整音量。
    我们可以控制"Audio Focus",让其他应用程序停止播放或降低音量,这样我们就可以在特定的流上清晰地播放声音,或者声音不会阻挡其他高优先级的声音,如电话铃声、导航语音反馈等像这样。

    由于多个应用可能会播放音频,因此考虑它们应该如何交互非常重要。为避免所有音乐应用同时播放,Android 使用音频焦点来调节音频播放——只有拥有音频焦点的应用才能播放音频。

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

    【讨论】:

    • @KeithYokoma。是否有可能通过其他流减少流量。我观察到 STREAM_VOICE_CALL 正在降低 STREAM_MUSIC 的音量?猜猜它是怎么发生的?
    【解决方案2】:

    像往常一样,无论您在 Google 中没有记录的内容(有时)都可以从代码中理解

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

    至于阻塞,实际上并不是流相互阻塞,只是模式阻塞了事物。 MODE_IN_COMMUNICATION 会阻止大部分流。

    闪避: 播放长时间运行的流(例如 MUSIC)时,一种常见且“礼貌”的行为是收听音频焦点回调并在“可以躲避”事件时手动降低流的音量。当焦点返回到您的流时,音量应该会恢复到之前的水平。

    流类型会影响流在给定时间对所有声音总和的贡献的音量:

       /** @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);
    

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

    【讨论】:

    • 您是否认为在使用录音和初始化音轨或其他录音时音轨或录音中的错误模式会静音或静音禁用麦克风?
    • 抱歉,没有对录音路径做足够的实验。很可能是一样的。不过,有些应用程序可以记录电话,有些应用程序可以随时显示音量,所以我想它在麦克风方面更灵活。麦克风是输入的,所以我想没有真正的冲突。相同的样本只适用于应用 A、B 或 C。也许是音量之类的,但这是一个小问题。
    • 好的!我理解并明白其中的逻辑。将查看通话记录器并进行调查!谢谢你的时间:)
    • 我在上面的答案中添加了一些代码片段,以显示使用不同流的一些效果(来自 Meymann 提到的代码。
    【解决方案3】:
    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

    【讨论】:

    • 很清楚它们的用途。我的问题是关于它们在低级别有何不同。它不能是 10 个相同的流。
    • 很明显,你可以读取标识符的名称......每个流的行为是什么?哪个在先?哪个在什么音频模式下播放?播放什么流时哪个鸭子?哪个受制于某种沉默机制?
    猜你喜欢
    • 2023-01-04
    • 1970-01-01
    • 2019-07-19
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2012-06-03
    相关资源
    最近更新 更多