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 <rgl@google.com> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31130}
This commit is contained in:
@ -10,8 +10,11 @@
|
|||||||
|
|
||||||
package org.webrtc.audio;
|
package org.webrtc.audio;
|
||||||
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.content.Context;
|
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.JniCommon;
|
||||||
import org.webrtc.Logging;
|
import org.webrtc.Logging;
|
||||||
|
|
||||||
@ -369,6 +372,18 @@ public class JavaAudioDeviceModule implements AudioDeviceModule {
|
|||||||
audioInput.setMicrophoneMute(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,
|
private static native long nativeCreateAudioDeviceModule(Context context,
|
||||||
AudioManager audioManager, WebRtcAudioRecord audioInput, WebRtcAudioTrack audioOutput,
|
AudioManager audioManager, WebRtcAudioRecord audioInput, WebRtcAudioTrack audioOutput,
|
||||||
int inputSampleRate, int outputSampleRate, boolean useStereoInput, boolean useStereoOutput);
|
int inputSampleRate, int outputSampleRate, boolean useStereoInput, boolean useStereoOutput);
|
||||||
|
@ -21,6 +21,7 @@ import android.media.MediaRecorder.AudioSource;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
import java.lang.System;
|
import java.lang.System;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -87,6 +88,7 @@ class WebRtcAudioRecord {
|
|||||||
|
|
||||||
private @Nullable AudioRecord audioRecord;
|
private @Nullable AudioRecord audioRecord;
|
||||||
private @Nullable AudioRecordThread audioThread;
|
private @Nullable AudioRecordThread audioThread;
|
||||||
|
private @Nullable AudioDeviceInfo preferredDevice;
|
||||||
|
|
||||||
private @Nullable ScheduledExecutorService executor;
|
private @Nullable ScheduledExecutorService executor;
|
||||||
private @Nullable ScheduledFuture<String> future;
|
private @Nullable ScheduledFuture<String> future;
|
||||||
@ -296,6 +298,9 @@ class WebRtcAudioRecord {
|
|||||||
// Throws IllegalArgumentException.
|
// Throws IllegalArgumentException.
|
||||||
audioRecord = createAudioRecordOnMOrHigher(
|
audioRecord = createAudioRecordOnMOrHigher(
|
||||||
audioSource, sampleRate, channelConfig, audioFormat, bufferSizeInBytes);
|
audioSource, sampleRate, channelConfig, audioFormat, bufferSizeInBytes);
|
||||||
|
if (preferredDevice != null) {
|
||||||
|
setPreferredDevice(preferredDevice);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Use the old AudioRecord constructor for API levels below 23.
|
// Use the old AudioRecord constructor for API levels below 23.
|
||||||
// Throws UnsupportedOperationException.
|
// Throws UnsupportedOperationException.
|
||||||
@ -329,6 +334,23 @@ class WebRtcAudioRecord {
|
|||||||
return framesPerBuffer;
|
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
|
@CalledByNative
|
||||||
private boolean startRecording() {
|
private boolean startRecording() {
|
||||||
Logging.d(TAG, "startRecording");
|
Logging.d(TAG, "startRecording");
|
||||||
|
Reference in New Issue
Block a user