feat: web/native device consistency management (#243)
* fix: Force audio settings to be consistent. * chore: applyAudioSettings for onUnpublish. * revert audio output select for web. * add RoomHardwareManagementMethods to Room. * update. * fix analyze. * update. * update. * chore: Reset sinkId for web when remoteTrack replays. * rename setAudioOutput to setSinkId for flutter web. * chore: Make sure AudioElement has `setSinkId` method.
This commit is contained in:
@@ -15,6 +15,16 @@ class LocalAudioTrack extends LocalTrack
|
||||
@override
|
||||
covariant AudioCaptureOptions currentOptions;
|
||||
|
||||
Future<void> setDeviceId(String deviceId) async {
|
||||
if (currentOptions.deviceId == deviceId) {
|
||||
return;
|
||||
}
|
||||
currentOptions = currentOptions.copyWith(deviceId: deviceId);
|
||||
if (!muted) {
|
||||
await restartTrack();
|
||||
}
|
||||
}
|
||||
|
||||
// private constructor
|
||||
@internal
|
||||
LocalAudioTrack(
|
||||
|
||||
@@ -229,4 +229,40 @@ class AudioCaptureOptions extends LocalTrackOptions {
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
|
||||
AudioCaptureOptions copyWith({
|
||||
String? deviceId,
|
||||
bool? noiseSuppression,
|
||||
bool? echoCancellation,
|
||||
bool? autoGainControl,
|
||||
bool? highPassFilter,
|
||||
bool? typingNoiseDetection,
|
||||
}) {
|
||||
return AudioCaptureOptions(
|
||||
deviceId: deviceId ?? this.deviceId,
|
||||
noiseSuppression: noiseSuppression ?? this.noiseSuppression,
|
||||
echoCancellation: echoCancellation ?? this.echoCancellation,
|
||||
autoGainControl: autoGainControl ?? this.autoGainControl,
|
||||
highPassFilter: highPassFilter ?? this.highPassFilter,
|
||||
typingNoiseDetection: typingNoiseDetection ?? this.typingNoiseDetection,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AudioOutputOptions {
|
||||
/// The deviceId of the output device to use.
|
||||
final String? deviceId;
|
||||
|
||||
/// If true, the audio will be played on the speaker.
|
||||
/// for mobile only
|
||||
final bool? speakerOn;
|
||||
|
||||
const AudioOutputOptions({this.deviceId, this.speakerOn});
|
||||
|
||||
AudioOutputOptions copyWith({String? deviceId, bool? speakerOn}) {
|
||||
return AudioOutputOptions(
|
||||
deviceId: deviceId ?? this.deviceId,
|
||||
speakerOn: speakerOn ?? this.speakerOn,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import '../web/_audio_api.dart' if (dart.library.html) '../web/_audio_html.dart'
|
||||
|
||||
class RemoteAudioTrack extends RemoteTrack
|
||||
with AudioTrack, RemoteAudioManagementMixin {
|
||||
//
|
||||
String? _deviceId;
|
||||
RemoteAudioTrack(String name, TrackSource source, rtc.MediaStream stream,
|
||||
rtc.MediaStreamTrack track,
|
||||
{rtc.RTCRtpReceiver? receiver})
|
||||
@@ -30,6 +30,9 @@ class RemoteAudioTrack extends RemoteTrack
|
||||
if (didStart) {
|
||||
// web support
|
||||
audio.startAudio(getCid(), mediaStreamTrack);
|
||||
if (_deviceId != null) {
|
||||
audio.setSinkId(getCid(), _deviceId!);
|
||||
}
|
||||
}
|
||||
return didStart;
|
||||
}
|
||||
@@ -44,7 +47,8 @@ class RemoteAudioTrack extends RemoteTrack
|
||||
return didStop;
|
||||
}
|
||||
|
||||
Future<void> setAudioOutput(String deviceId) async {
|
||||
audio.setAudioOutput(getCid(), deviceId);
|
||||
Future<void> setSinkId(String deviceId) async {
|
||||
audio.setSinkId(getCid(), deviceId);
|
||||
_deviceId = deviceId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ void stopAudio(String id) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void setAudioOutput(String id, String deviceId) {
|
||||
void setSinkId(String id, String deviceId) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'dart:html' as html;
|
||||
|
||||
import 'dart:js_util' as jsutil;
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||
|
||||
// ignore: implementation_imports
|
||||
@@ -52,9 +52,10 @@ html.DivElement findOrCreateAudioContainer() {
|
||||
return div as html.DivElement;
|
||||
}
|
||||
|
||||
void setAudioOutput(String id, String deviceId) {
|
||||
void setSinkId(String id, String deviceId) {
|
||||
final audioElement = html.document.getElementById(audioPrefix + id);
|
||||
if (audioElement is html.AudioElement) {
|
||||
if (audioElement is html.AudioElement &&
|
||||
jsutil.hasProperty(audioElement, 'setSinkId')) {
|
||||
audioElement.setSinkId(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user