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:
CloudWebRTC
2023-03-07 17:54:06 +08:00
committed by GitHub
parent 70e6589981
commit db2e25d424
12 changed files with 275 additions and 136 deletions
+10
View File
@@ -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(
+36
View File
@@ -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,
);
}
}
+7 -3
View File
@@ -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;
}
}
+1 -1
View File
@@ -8,6 +8,6 @@ void stopAudio(String id) {
// do nothing
}
void setAudioOutput(String id, String deviceId) {
void setSinkId(String id, String deviceId) {
// do nothing
}
+4 -3
View File
@@ -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);
}
}