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 void setMicrophoneMute(boolean mute) { 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.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 @@ private int initRecording(int sampleRate, int channels) { // 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 @@ private int initRecording(int sampleRate, int channels) { 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");