Skip to content

Commit

Permalink
Merge pull request #12 from flutter-webrtc/dl/selectaudio
Browse files Browse the repository at this point in the history
select audio output and ondevicechange methods
  • Loading branch information
cloudwebrtc authored Aug 4, 2022
2 parents c629ad2 + 1b6caea commit e4fd32a
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 8 deletions.
64 changes: 64 additions & 0 deletions lib/src/mediadevices_impl.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'dart:async';
import 'dart:html' as html;
import 'dart:html_common';
import 'dart:js' as js;
import 'dart:js_util' as jsutil;
import 'package:webrtc_interface/webrtc_interface.dart';

Expand Down Expand Up @@ -126,4 +128,66 @@ class MediaDevicesWeb extends MediaDevices {
width: _mapConstraints['width'],
zoom: _mapConstraints['zoom']);
}

@override
Future<MediaDeviceInfo> selectAudioOutput(
[AudioOutputOptions? options]) async {
try {
final mediaDevices = html.window.navigator.mediaDevices;
if (mediaDevices == null) throw Exception('MediaDevices is null');

if (jsutil.hasProperty(mediaDevices, 'selectAudioOutput')) {
if (options != null) {
final arg = jsutil.jsify(options);
final deviceInfo = await jsutil.promiseToFuture<html.MediaDeviceInfo>(
jsutil.callMethod(mediaDevices, 'selectAudioOutput', [arg]));
return MediaDeviceInfo(
kind: deviceInfo.kind,
label: deviceInfo.label ?? '',
deviceId: deviceInfo.deviceId ?? '',
groupId: deviceInfo.groupId,
);
} else {
final deviceInfo = await jsutil.promiseToFuture<html.MediaDeviceInfo>(
jsutil.callMethod(mediaDevices, 'selectAudioOutput', []));
return MediaDeviceInfo(
kind: deviceInfo.kind,
label: deviceInfo.label ?? '',
deviceId: deviceInfo.deviceId ?? '',
groupId: deviceInfo.groupId,
);
}
} else {
throw UnimplementedError('selectAudioOutput is missing');
}
} catch (e) {
throw 'Unable to selectAudioOutput: ${e.toString()}, Please try to use MediaElement.setSinkId instead.';
}
}

@override
set ondevicechange(Function(dynamic event)? listener) {
try {
final mediaDevices = html.window.navigator.mediaDevices;
if (mediaDevices == null) throw Exception('MediaDevices is null');

jsutil.setProperty(mediaDevices, 'ondevicechange',
js.allowInterop((evt) => listener?.call(evt)));
} catch (e) {
throw 'Unable to set ondevicechange: ${e.toString()}';
}
}

@override
Function(dynamic event)? get ondevicechange {
try {
final mediaDevices = html.window.navigator.mediaDevices;
if (mediaDevices == null) throw Exception('MediaDevices is null');

jsutil.getProperty(mediaDevices, 'ondevicechange');
} catch (e) {
throw 'Unable to get ondevicechange: ${e.toString()}';
}
return null;
}
}
3 changes: 2 additions & 1 deletion lib/src/rtc_video_element.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:html' as html;

import '../dart_webrtc.dart';
import 'media_stream_impl.dart';

class RTCVideoElement {
RTCVideoElement() {
Expand Down Expand Up @@ -61,4 +60,6 @@ class RTCVideoElement {
void load() => _html.load();

void removeAttribute(String name) => _html.removeAttribute(name);

Future<void> setSinkId(String sinkId) => _html.setSinkId(sinkId);
}
34 changes: 27 additions & 7 deletions web/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,43 @@ void loopBackTest() async {
var localVideo = RTCVideoElement();
local!.append(localVideo.htmlElement);

//var pc = await createPeerConnection({});
//pc.onAddStream = (MediaStream stream) {};
var stream =
await navigator.mediaDevices.getUserMedia({'audio': true, 'video': true});
/*.getUserMedia(MediaStreamConstraints(audio: true, video: true))*/
print('getDisplayMedia: stream.id => ${stream.id}');

navigator.mediaDevices.ondevicechange = (event) async {
var list = await navigator.mediaDevices.enumerateDevices();
print('ondevicechange: ');
list.where((element) => element.kind == 'audiooutput').forEach((e) {
print('${e.runtimeType}: ${e.label}, type => ${e.kind}');
});
};

var list = await navigator.mediaDevices.enumerateDevices();
list.forEach((e) {
print('${e.runtimeType}: ${e.label}, type => ${e.kind}');
});
var outputList = list.where((element) => element.kind == 'audiooutput');
if (outputList.isNotEmpty) {
var sinkId = outputList.last.deviceId;
try {
await navigator.mediaDevices
.selectAudioOutput(AudioOutputOptions(deviceId: sinkId));
} catch (e) {
print('selectAudioOutput error: ${e.toString()}');
await localVideo.setSinkId(sinkId);
}
}

var pc = await createPeerConnection({});
pc.onAddStream = (MediaStream stream) {};
var stream =
await navigator.mediaDevices.getUserMedia({'audio': true, 'video': true});
/*.getUserMedia(MediaStreamConstraints(audio: true, video: true))*/
print('getDisplayMedia: stream.id => ${stream.id}');
/*
stream.oninactive = (Event event) {
print('oninactive: stream.id => ${event.target.id}');
localVideo.srcObject = null;
};
*/
await pc.addStream(stream);
//await pc.addStream(stream);
localVideo.srcObject = stream;
}

0 comments on commit e4fd32a

Please sign in to comment.