首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AudioManager正在setMode(MODE_IN_COMMUNICATION)中引入延迟

AudioManager正在setMode(MODE_IN_COMMUNICATION)中引入延迟
EN

Stack Overflow用户
提问于 2017-12-06 14:41:35
回答 1查看 1.6K关注 0票数 8

我试着在扬声器上播放声音,即使耳机是开着的,但是如果有音乐在背景中播放,我希望在播放声音之前在耳机上播放音乐。

因此,我将采取以下步骤:

  • 在播放声音之前,我获得了audioFocus,所以所有的背景音乐都停止了。
  • 在获得audioFocus之后,我将MODE_COMMUNICATION设置为AudioManager,这样就可以在扬声器上播放声音。
  • 声音结束后,我abandonAudioFocus并将MODE_NORMAL设置为AudioManager,这样背景音乐就可以继续在耳机上播放了。

奇怪的是,这取决于设备,在某些设备上--这是可以的,,但是在Nexus6P(华为)设备上,在设置之后,还有3-4秒才能播放声音。如果我在没有延迟的情况下播放声音,它既不会播放到扬声器也不会播放到耳机。

问题

在播放声音之前,我怎么知道要延迟多少时间呢?是否有我可以附加的侦听器,所以可以通知我,在设置MODE_COMMUNICATION之后,声音就可以播放了?

我不想设置延迟,即使没有必要!

解决方案不是将模式设置为类的构造函数(跳过延迟),因为我需要在特定时刻在扬声器上播放声音!

我正在用AudioTrack播放声音,但我也尝试过用MediaPlayer (设置setAudioStreamType(MODE_IN_COMMUNICATION)),但是没有成功,延迟仍然存在!

有什么建议吗?

EN

回答 1

Stack Overflow用户

发布于 2020-05-02 10:21:41

如果有人无意中看到这篇文章,对我起作用的是调用AudioManager.setMode(),然后重新创建我的MediaPlayer (通过构造函数,而不是create()),并使用setAudioAttributes()更改输出源。

Kotlin片段:

代码语言:javascript
复制
fun switchOutput(inCommunication: Boolean) {

    //STEP 1: Change the AudioManager's audio mode
    if(inCommunication) {
        audioManager.mode = AudioManager.MODE_IN_CALL
        audioManager.isSpeakerphoneOn = false
    } else {
        audioManager.mode = AudioManager.MODE_NORMAL
        audioManager.isSpeakerphoneOn = true
    }

    //STEP 2: Recreate the MediaPlayer
    if (player != null) {
        try {
            player?.stop()
        } catch (e: RuntimeException) {
        } finally {
            player?.reset()
            player?.release()
            player = null
        }
    }

    player = MediaPlayer()
    try {
        val streamType =
                if (inCommunication) AudioManager.STREAM_VOICE_CALL
                else AudioManager.STREAM_MUSIC
        player?.setDataSource(dataSource)
        player?.setAudioAttributes(AudioAttributes.Builder()
                .setLegacyStreamType(streamType)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build())
        player?.prepare()
        player?.start()
    } catch (e: java.lang.Exception) {}
}

希望这会有所帮助:)

注意,我用的是MODE_IN_CALL而不是MODE_IN_COMMUNICATION

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47676936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档