java - AudioManager 在 setMode(MODE_IN_COMMUNICATION) 中引入延迟

标签 java android android-mediaplayer android-audiomanager audiotrack

即使打开耳机,我也试图在扬声器上播放声音,但如果背景中有音乐播放,我希望在耳机上播放音乐直到播放声音。

所以我正在采取接下来的步骤:

  • 在我播放声音之前,我获得了 audioFocus 所以所有的背景音乐都是
    停止
  • 获得audioFocus后,我设置MODE_COMMUNICATION
    AudioManager,因此可以在扬声器上播放声音。
  • 声音结束后,我放弃AudioFocus,重新设置MODE_NORMALAudioManager ,所以背景音乐可以在耳机上继续播放。

  • 奇怪的是它取决于设备,在某些设备上这是可以的,但在 Nexus 6P (Huawei) 设备上设置 MODE_COMMUNICATION在播放声音之前有 3-4 秒的延迟。如果我没有延迟播放声音,它既不会播放到扬声器也不会播放到耳机。

    问题

    我怎么知道在播放声音之前要设置多少延迟?有没有我可以附加的监听器,所以可以在设置 MODE_COMMUNICATION 后通知我声音准备好播放了吗?

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

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

    P.S:我正在用 AudioTrack 播放声音,但我尝试使用 MediaPlayer以及(设置 setAudioStreamType(MODE_IN_COMMUNICATION) ),但没有成功,延迟仍然存在!

    那么有什么建议吗?

    最佳答案

    万一有人偶然发现这篇文章,对我有用的是调用 AudioManager.setMode()然后重新创建我的MediaPlayer (通过构造函数,而不是 create() )并使用 setAudioAttributes()更改输出源。

    Kotlin fragment :

    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

    关于java - AudioManager 在 setMode(MODE_IN_COMMUNICATION) 中引入延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47676936/

    相关文章:

    java - 尝试使用本地代理类型连接到 SSH 服务器?

    java - 未处理的警报异常 : Modal Dialog Present (Selenium)

    java - 损坏的绘图程序。 java

    android - Android Studio 中的变量安全

    android - 为什么我的应用程序在启动时崩溃 (Android Studio)

    安卓NDK : how to make the command "ndk-gdb --help" work in console?

    java - 如何在线创建和验证 Onedrive 或 Sharepoint 的 Webhook?

    java - 一段时间后声音停止

    android - 如何解决服务类的 ' ANR Reason: executing service ' 错误?

    android - 使用 AssetFileDescriptor 播放音频不起作用