当前位置: 首页 > 知识库问答 >
问题:

通过耳机传送麦克风输入,通过手机扬声器传送音频输出

姚韬
2023-03-14

有没有办法通过耳机传送麦克风输入,同时通过智能手机扬声器使用音频输出?

我已经看了几个小时了,我看到这在iOS上显然是不可能的,但是Android呢...

我用的是三星Galaxy S4。

这是我的代码的一部分,即使耳机已插入,也可以通过扬声器路由音频输出:

AudioManager speakerOutput = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
speakerOutput.setMode(AudioManager.MODE_IN_CALL);
speakerOutput.setSpeakerphoneOn(true);

但当我试图通过耳机的麦克风控制我的应用程序时,什么都没有。所以我试着用智能手机的那一个,它显然起作用了。

它看起来不像其他AudioManager。MODE仅路由音频输出并将麦克风输入留给耳机。那么我现在可以做什么而不必构建新内核、修改驱动程序、HAL等?

谢谢,C。

共有3个答案

苏丰茂
2023-03-14

是的,这是可能的。几天前我成功地做到了这一点。有两种解决方案:

解决方案1:

假设你心情正常

@RequiresApi(Build.VERSION_CODES.P)
private fun playAudioFromPhoneSpeaker(context: Context, audioResId: Int) {
    val mMediaPlayer: MediaPlayer = MediaPlayer.create(context, audioResId)
    val mCurrentDevice: AudioDeviceInfo? = mMediaPlayer.preferredDevice
    val mDeviceSpeaker: AudioDeviceInfo? = getDeviceOutputSpeaker(context)
    mDeviceSpeaker?.let { speaker ->
        if (mCurrentDevice != speaker) {
            val result: Boolean? = mMediaPlayer.setPreferredDevice(mDeviceSpeaker)
            Log.i("PreferredDevice", "is set as speaker: $result")
        }
    }
    mMediaPlayer.start()
    mMediaPlayer.setOnCompletionListener { mediaPlayer ->
        mediaPlayer.release()
    }
}

@RequiresApi(Build.VERSION_CODES.M)
private fun getDeviceOutputSpeaker(context: Context): AudioDeviceInfo? {
    val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    val mAudioDeviceOutputList = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
    mAudioDeviceOutputList?.filterNotNull()?.forEach { speaker ->
        if (speaker.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
            return speaker
        }
    }
    return null
}

这个解决方案的积极之处在于,我们不需要考虑输入源。我们只更改音频输出源,对输入源没有任何影响。

问题是setPreferredDevice的MediaPlayer来自Android 9。因此,此解决方案仅受Android 9支持。

解决方案2:

在第二种解决方案中,我们通过音频管理器打开设备扬声器。因此,打开设备扬声器后,音频输入

private val mAudioRecord: AudioRecord? = null
private fun RecordAudioFromHeadphone(context: Context) {
    //Step 1: Turn on Speaker
    val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    audioManager.isSpeakerphoneOn = true

    //Step 2: Init AudioRecorder TODO for you

    //Step 3: Route mic to headset
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        setPreferredInputMic(getWiredHeadPhoneMic(this))
    }
}

@RequiresApi(Build.VERSION_CODES.M)
private fun setPreferredInputMic(mAudioDeviceInfo: AudioDeviceInfo?) {
    val result: Boolean? = mAudioRecord?.setPreferredDevice(mAudioDeviceInfo)
}

@RequiresApi(Build.VERSION_CODES.M)
private fun getWiredHeadPhoneMic(context: Context): AudioDeviceInfo? {
    val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    val mAudioDeviceOutputList = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
    mAudioDeviceOutputList?.filterNotNull()?.forEach { device ->
        if (device.type == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
            return device
        }
    }
    return null
}

Android 6支持此解决方案的积极想法。消极的是它有点复杂,你必须维护语音输入源。

AudioRecorder、MediaRecorder、AudioTrack也支持这种解决方案。

谢啦

花玄裳
2023-03-14

如果您使用AudioManager。STREAM\u RING(流音)时,音频应同时发送到扬声器和有线耳机,就像为来电播放铃声一样(删除设置模式和设置扬声器电话)。

蒯慈
2023-03-14

如果您不更改Android上的HAL或驱动程序,就无法从耳机麦克风回传到扬声器。如果你能改变硬件,它可能会成功。

 类似资料:
  • 我正在尝试创建一个麦克风应用程序,在会议中用作观众的真正麦克风。我们将把Android设备连接到Wi-Fi局域网,任何人都可以从他们的应用程序中触发麦克风,向他人讲话。数据将进入局域网内的服务器Java程序,并从那里进入扬声器。 我不知道该怎么做。有人能帮我吗???提前谢谢

  • 我想用插入式耳机通过扬声器播放音频文件。 但我得到了 IllegalStateException 有什么想法可以解决这个问题吗?

  • 在一些移动设备中(如摩托罗拉One Power-Android10、Redmi Note 5 Pro-Android7.1.2),来自手机扬声器的声音通过手机麦克风进入会议并产生回声。只有当手机扬声器处于打开状态时,才会出现此回声问题。 我使用了AudioManagerMODE_IN_COMMUNICATION模式: 此外,在音频约束下使用PeerConnectionFactory的createA

  • 我试图让用户能够在我的应用程序中切换音频输出,我可以使用AVAudioSession在扬声器和背部之间切换,但我找不到在连接的蓝牙设备和耳机之间切换的方法,以任何顺序。 谢谢你的帮助。

  • 问题的标题可能看起来重复,但我的问题有时是一个问题,会导致故障。当插入耳机时,我使用以下代码通过扬声器播放。 上面的代码以以下方式播放音频:1.很少时候,它可以完美播放。2.大多数时候,它在背景中播放循环声音。3.很少时候,它什么都不播放。 插入耳机时,系统声音播放似乎没有错误。例如-设置铃声正确播放相应的铃声,没有任何故障。请帮助我了解如何在插入耳机的情况下通过扬声器正确播放声音。

  • 我在我的应用程序中为某些通知添加声音,就像这样: 播放通知声音时,即使将耳机插入手机,也会通过扬声器播放,因此扬声器和耳机都会播放该声音。 如果插上耳机,有没有办法只通过耳机播放声音?