Bluetooth headset on WebRTC

Google様がやっているWebRTC https://webrtc.org

これのAndroid native clientを使ってみたのだけど、Bluetoothのheadsetをpairngしても音声とマイクが本体につながってて、BTデバイスにroutingされないので、ちょっといじってみた。

結論からいうとAppRTCAudioManager.javaを弄る必要がありますが、とくに難しいことはありません。

※ BT接続のところは適当です。

public enum AudioDevice {
    SPEAKER_PHONE,
    WIRED_HEADSET,
    EARPIECE,
+    BLUETOOTH_HEADSET
  }

  public void init() {
    Log.d(TAG, "init");
    if (initialized) {
      return;
    }
___snip___
-    updateAudioDeviceState(hasWiredHeadset());
+    boolean btConnected = isBtHeadsetConnected();
+    updateAudioDeviceState(hasWiredHeadset(), btConnected);
+
+    // ここかなりサボってます。
+    // 本当はBT接続処理をちゃんとしないとだめですよ
+    if (btConnected) {
+      audioManager.startBluetoothSco();
+      audioManager.setBluetoothScoOn(true);
+    } else {

      // Register receiver for broadcast intents related to adding/removing a
      // wired headset (Intent.ACTION_HEADSET_PLUG).
      registerForWiredHeadsetIntentBroadcast();
+    }
___snip___



  /** Changes selection of the currently active audio device. */
  public void setAudioDevice(AudioDevice device) {
    Log.d(TAG, "setAudioDevice(device=" + device + ")");
    AppRTCUtils.assertIsTrue(audioDevices.contains(device));

    switch (device) {
      case SPEAKER_PHONE:
        setSpeakerphoneOn(true);
        selectedAudioDevice = AudioDevice.SPEAKER_PHONE;
        break;
      case EARPIECE:
        setSpeakerphoneOn(false);
        selectedAudioDevice = AudioDevice.EARPIECE;
        break;
      case WIRED_HEADSET:
        setSpeakerphoneOn(false);
        selectedAudioDevice = AudioDevice.WIRED_HEADSET;
        break;
+      case BLUETOOTH_HEADSET:
+        setSpeakerphoneOn(false);
+        selectedAudioDevice = AudioDevice.BLUETOOTH_HEADSET;
+        break;
      default:
        Log.e(TAG, "Invalid audio device selection");
        break;
    }
    onAudioManagerChangedState();
  }

+  private boolean isBtHeadsetConnected() {
+
+    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+    Set<BluetoothDevice> devices = adapter.getBondedDevices();
+
+    return (adapter.getProfileConnectionState(BluetoothProfile.HEADSET) ==
+            BluetoothProfile.STATE_CONNECTED);
+  }

  /** Unregister receiver for broadcasted ACTION_HEADSET_PLUG intent. */
  private void unregisterForWiredHeadsetIntentBroadcast() {
-    apprtcContext.unregisterReceiver(wiredHeadsetReceiver);
-    wiredHeadsetReceiver = null;
+    if (wiredHeadsetReceiver != null) {
+      apprtcContext.unregisterReceiver(wiredHeadsetReceiver);
+      wiredHeadsetReceiver = null;
+    }
  }

  /** Update list of possible audio devices and make new device selection. */
+  private void updateAudioDeviceState(boolean hasWiredHeadset, boolean hasBtHeadset) {
+    // Update the list of available audio devices.
+    audioDevices.clear();
+    if (hasBtHeadset) {
+      audioDevices.add(AudioDevice.BLUETOOTH_HEADSET);
+      setAudioDevice(AudioDevice.BLUETOOTH_HEADSET);
+    } else {
+      updateAudioDeviceState(hasWiredHeadset);
+    }
+  }

ちなみにWired headsetはオリジナルのコードでちゃんと動いてました。

そのうちちゃんと勉強しようっと。

WebRTC ブラウザベースのP2P技術

WebRTC ブラウザベースのP2P技術

TypeScriptネットワークプログラミング―HTML5/WebSocket/WebRTCによる

TypeScriptネットワークプログラミング―HTML5/WebSocket/WebRTCによる