【问题标题】:One device doesn't play audio call through earpiece after enabling microphone启用麦克风后,一台设备无法通过听筒播放音频通话
【发布时间】:2020-04-09 16:07:13
【问题描述】:

我正在编写信使(具有 VoIP 功能),用户可以在其中单独关闭/打开扬声器和麦克风。我刚刚添加了一个功能,用户可以将手机放在耳边,然后屏幕关闭,他可以通过耳机听到对话。这是问题所在。在一台设备上(使用自定义固件),当我同时打开扬声器和麦克风并将手机放在耳边时,我什么也听不见。

我的部分代码:

打开扬声器:

private void headsetStart()
{
    if (mPlayMessages == null)
    {
        mHeadsetButton.setBackgroundResource(R.drawable.headset_on);

        audioManager.setMode(audioManager.MODE_IN_COMMUNICATION);
        audioManager.setSpeakerphoneOn(!nearProximity);

        // turn off screen on near proximity sensor
        mWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, ":headsetStart");
        mWakeLock.acquire();
        mBeOnAirThread = new BeOnAirThread();
        mBeOnAirThread.start();

        if (partnerOnAir && !mIsStarted)
        {
            micStart();
        }
    }
}

private class BeOnAirThread extends Thread {

    // Sample rate must be one supported by Opus.
    static final int SAMPLE_RATE = 16000;

    // Number of samples per frame is not arbitrary,
    // it must match one of the predefined values, specified in the standard.
    static final int FRAME_SIZE = 160;

    // 1 or 2
    static final int NUM_CHANNELS = 1;

    @Override
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);

        int minBufSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                NUM_CHANNELS == 1 ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO,
                AudioFormat.ENCODING_PCM_16BIT);

        // init audio track
        AudioTrack track = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
                SAMPLE_RATE,
                NUM_CHANNELS == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO,
                AudioFormat.ENCODING_PCM_16BIT,
                minBufSize,
                AudioTrack.MODE_STREAM);
.....................................

初始化麦克风:

private class RecordThread extends Thread {
    // Sample rate must be one supported by Opus.
    static final int SAMPLE_RATE = 16000;

    // Number of samples per frame is not arbitrary,
    // it must match one of the predefined values, specified in the standard.
    static final int FRAME_SIZE = 160;

    // 1 or 2
    static final int NUM_CHANNELS = 1;

    byte[] textBuf;
    int iav;
    int off;

    @Override
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);

        int minBufSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                NUM_CHANNELS == 1 ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO,
                AudioFormat.ENCODING_PCM_16BIT);

        // initialize audio recorder
        AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
                SAMPLE_RATE,
                NUM_CHANNELS == 1 ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO,
                AudioFormat.ENCODING_PCM_16BIT,
                minBufSize);
..........................................

经验证明,如果在“audioManager.setSpeakerphoneOn(!nearProximity)”之前停止 RecordThread 并在它之后重新启动它,那么耳机就可以工作。 但是对我来说重新连接到服务器是不可取的。所以我也尝试在“audioManager.setSpeakerphoneOn(!nearProximity)”之前做“recorder.stop();recorder.release()”并在它之后重建新的AudioRecord,但它没有帮助。

有什么想法吗?

【问题讨论】:

    标签: android voip


    【解决方案1】:

    终于成功了。

    实验表明我真的不需要发布和重建 AudioRecord。

    我所需要的只是“audioManager.setSpeakerphoneOn(!nearProximity);”之间的一些延迟(约 1 秒)和“recorder.startRecording();”

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
            boolean oldNear = nearProximity;
            if (event.values[0] >= -SENSOR_SENSITIVITY && event.values[0] <= SENSOR_SENSITIVITY) {
                nearProximity = true;
            } else {
                nearProximity = false;
            }
    
            if (mBeOnAirThread != null && oldNear != nearProximity)
            {
                if (nearProximity && mIsStarted)
                    nearChanged = true;
                else
                    audioManager.setSpeakerphoneOn(!nearProximity);
            }
        }
    }
    

    在记录循环中:

                    if (nearChanged)
                    {
                        recorder.stop();
                        audioManager.setSpeakerphoneOn(!nearProximity);
    
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        }
    
                        recorder.startRecording();
                        nearChanged = false;
                    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-16
      • 1970-01-01
      • 2015-10-31
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多