Android-从蓝牙耳机录制音频有时从麦克风录制



我正在尝试从蓝牙耳机录制音频并对其进行分析,为此我使用了对象:android.media.AudioRecord,我的问题是,对于一些与安卓版本相结合的设备,我从手机麦克风而不是蓝牙耳机获得录音。

在某些情况下,我可以解决这个问题——如果当我创建这个对象时,我将不同的音频源类型传递给它的构造函数。

例如,我看到,为了在Nexus 6和Android 5.0中使用蓝牙耳机进行录制,我需要构建这样的AudioRecord:

audioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 4410);

但如果我试着对一款名为"THL T6S"的手机使用相同的代码,它也有Android 5.0,录音来自手机麦克风。如果我想从这款手机的耳机中获得它,我需要写下:

audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 4410);

但当然,我无法在代码中涵盖手机类型和操作系统版本的所有可能组合。

我该如何解决?

附上所有相关代码。

谢谢。

这是我的蓝牙Sco级

public class BluetoothSco {
private static BluetoothSco instance = null;
// Context
private Context mContext;
private Service service;
// Logcat TAG
private final String TAG = BluetoothSco.class.getSimpleName();
// AudioMode
public static final int MODE_IN_CALL = 1;
public static final int MODE_IN_COMMUNICATION = 2;
public static final int MODE_NORMAL = 3;
// BluetoothAdapter
private final BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
protected BluetoothSco() { }
public static BluetoothSco getInstance(Context context) {
    if(instance == null) {
        instance = new BluetoothSco();
        instance.mContext = context;
        instance.service = (Service) context;
    }
    return instance;
}
// Start Sco
public synchronized void startSco(final int audioMode) {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            if (btAdapter == null) {
                Log.i(TAG, "This device does not support Bluetooth");
                return;
            }
            else if (!btAdapter.isEnabled()) {
                Log.i(TAG, "Bluetooth headset is disconnected. Would you like to monitor manually?");
                return;
            }
            AudioManager audioManager = (AudioManager) service.getSystemService(Context.AUDIO_SERVICE);
            if (!audioManager.isBluetoothScoAvailableOffCall()) {
                Log.i(TAG, "Off-call Bluetooth audio not supported on this device.");
                return;
            }
            if (audioMode == BluetoothSco.MODE_IN_CALL) {
                audioManager.setMode(AudioManager.MODE_IN_CALL);
            }
            else if (audioMode == BluetoothSco.MODE_IN_COMMUNICATION) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
                }
                else {
                    audioManager.setMode(AudioManager.MODE_NORMAL);
                }
            }
            else if (audioMode == BluetoothSco.MODE_NORMAL) {
                audioManager.setMode(AudioManager.MODE_NORMAL);
            }

            //Roni - temp code/////////
            //audioManager.setMode(AudioManager.MODE_IN_CALL);
            ////////////////////
            audioManager.setBluetoothScoOn(true);
            try{
                audioManager.startBluetoothSco();
                Log.v(TAG, "Bluetooth SCO Started");
            }
            catch(NullPointerException ex){
                Log.i(TAG, "Bluetooth headset is disconnected. Would you like to monitor manually?");
            }
        }
    };
    runnable.run();
}
public synchronized void stopSco() {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            AudioManager audioManager = (AudioManager) service.getSystemService(Context.AUDIO_SERVICE);
            try {
                audioManager.setBluetoothScoOn(false);
                audioManager.stopBluetoothSco();
                audioManager.setMode(AudioManager.MODE_NORMAL);
                Log.v(TAG, "Bluetooth SCO Stopped");
            }
            catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }
    };
    runnable.run();
}

}

以下是我如何初始化AudioRecord和蓝牙Sco

audioRecord = new AudioRecord(Options.audioSource, Options.sampleRate, Options.channelConfig,
                Options.audioEncoding, Options.numBuffers * Math.max(minBufSize,  bufferSizeBytes));
mBluetoothSco.startSco(BluetoothSco.MODE_NORMAL);
audioRecord.startRecording();

我也遇到了同样的问题。对我来说,添加以下内容修复了这个问题:

    audioManager.setMode(AudioManager.VOICE_COMMUNICATION);

代码需要注意的细节(摘要):

  1. 设置AudioManager模式并启动SCO
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.setBluetoothScoOn(true);
mAudioManager.startBluetoothSco();
  1. AudioRecord使用VOICE_COMMUNICATION进行初始化,在此处输入链接描述
new AudioRecord(VOICE_COMMUNICATION, sampleRateInHz, channelConfig, audioFormat, recordingBufferSize)

通过这些,我可以使用蓝牙在React Native中进行录制。

相关内容

  • 没有找到相关文章

最新更新