From 97755813dd9b9ffee255e4e4e2b47f26ddcc2994 Mon Sep 17 00:00:00 2001 From: Robin Lee Date: Fri, 24 Apr 2020 16:23:28 +0200 Subject: [PATCH] Reland "Add an optional override for AudioRecord device" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a reland of 1b8ef63876ebfa55a51c8ca9b1d8206bf8233e01. It was previously reverted (https://webrtc-review.googlesource.com/c/src/+/175008) but the revert was found to be unnecessary. Original change's description: > Add an optional override for AudioRecord device > > This is important when we have multiple named devices connected over > USB (eg. "Webcam", "Microphone", "Headset") and there is some way to > choose a specific input device to route from. > > Bug: b/154440591 > Change-Id: I8dc1801a5e4db7f7bb439e855d43897c1f7d8bc4 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/173748 > Commit-Queue: Robin Lee > Reviewed-by: Sami Kalliomäki > Reviewed-by: Henrik Andreassson > Cr-Commit-Position: refs/heads/master@{#31130} TBR=henrika@webrtc.org,sakal@webrtc.org,rgl@google.com Bug: b/154440591, b/155256727 Change-Id: Ic9bf8305c85552a0dc0d2cde6190988423e7fc70 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/175084 Reviewed-by: Henrik Lundin Commit-Queue: Henrik Lundin Cr-Commit-Position: refs/heads/master@{#31255} --- .../webrtc/audio/JavaAudioDeviceModule.java | 17 +++++++++++++- .../org/webrtc/audio/WebRtcAudioRecord.java | 22 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/sdk/android/api/org/webrtc/audio/JavaAudioDeviceModule.java b/sdk/android/api/org/webrtc/audio/JavaAudioDeviceModule.java index ece6f35d4c..9ae00c51b7 100644 --- a/sdk/android/api/org/webrtc/audio/JavaAudioDeviceModule.java +++ b/sdk/android/api/org/webrtc/audio/JavaAudioDeviceModule.java @@ -10,8 +10,11 @@ package org.webrtc.audio; -import android.media.AudioManager; import android.content.Context; +import android.media.AudioDeviceInfo; +import android.media.AudioManager; +import android.os.Build; +import android.support.annotation.RequiresApi; import org.webrtc.JniCommon; import org.webrtc.Logging; @@ -369,6 +372,18 @@ public class JavaAudioDeviceModule implements AudioDeviceModule { audioInput.setMicrophoneMute(mute); } + /** + * Start to prefer a specific {@link AudioDeviceInfo} device for recording. Typically this should + * only be used if a client gives an explicit option for choosing a physical device to record + * from. Otherwise the best-matching device for other parameters will be used. Calling after + * recording is started may cause a temporary interruption if the audio routing changes. + */ + @RequiresApi(Build.VERSION_CODES.M) + public void setPreferredInputDevice(AudioDeviceInfo preferredInputDevice) { + Logging.d(TAG, "setPreferredInputDevice: " + preferredInputDevice); + audioInput.setPreferredDevice(preferredInputDevice); + } + private static native long nativeCreateAudioDeviceModule(Context context, AudioManager audioManager, WebRtcAudioRecord audioInput, WebRtcAudioTrack audioOutput, int inputSampleRate, int outputSampleRate, boolean useStereoInput, boolean useStereoOutput); diff --git a/sdk/android/src/java/org/webrtc/audio/WebRtcAudioRecord.java b/sdk/android/src/java/org/webrtc/audio/WebRtcAudioRecord.java index b7b78f731f..018196b784 100644 --- a/sdk/android/src/java/org/webrtc/audio/WebRtcAudioRecord.java +++ b/sdk/android/src/java/org/webrtc/audio/WebRtcAudioRecord.java @@ -21,6 +21,7 @@ import android.media.MediaRecorder.AudioSource; import android.os.Build; import android.os.Process; import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; import java.lang.System; import java.nio.ByteBuffer; import java.util.Arrays; @@ -87,6 +88,7 @@ class WebRtcAudioRecord { private @Nullable AudioRecord audioRecord; private @Nullable AudioRecordThread audioThread; + private @Nullable AudioDeviceInfo preferredDevice; private @Nullable ScheduledExecutorService executor; private @Nullable ScheduledFuture future; @@ -296,6 +298,9 @@ class WebRtcAudioRecord { // Throws IllegalArgumentException. audioRecord = createAudioRecordOnMOrHigher( audioSource, sampleRate, channelConfig, audioFormat, bufferSizeInBytes); + if (preferredDevice != null) { + setPreferredDevice(preferredDevice); + } } else { // Use the old AudioRecord constructor for API levels below 23. // Throws UnsupportedOperationException. @@ -329,6 +334,23 @@ class WebRtcAudioRecord { return framesPerBuffer; } + /** + * Prefer a specific {@link AudioDeviceInfo} device for recording. Calling after recording starts + * is valid but may cause a temporary interruption if the audio routing changes. + */ + @RequiresApi(Build.VERSION_CODES.M) + @TargetApi(Build.VERSION_CODES.M) + void setPreferredDevice(@Nullable AudioDeviceInfo preferredDevice) { + Logging.d( + TAG, "setPreferredDevice " + (preferredDevice != null ? preferredDevice.getId() : null)); + this.preferredDevice = preferredDevice; + if (audioRecord != null) { + if (!audioRecord.setPreferredDevice(preferredDevice)) { + Logging.e(TAG, "setPreferredDevice failed"); + } + } + } + @CalledByNative private boolean startRecording() { Logging.d(TAG, "startRecording");