manually handle audio tracks for web

This commit is contained in:
David Zhao
2021-08-26 22:58:04 -07:00
parent 82322be783
commit 3a26044399
7 changed files with 104 additions and 21 deletions
+4 -3
View File
@@ -1,9 +1,10 @@
import 'room.dart';
import 'signal_client.dart';
class LiveKitClient {
// TODO: take in connect options
static Future<Room> connect(String url, String token) {
static Future<Room> connect(String url, String token,
[JoinOptions? options]) {
var room = Room();
return room.connect(url, token);
return room.connect(url, token, options);
}
}
+4 -1
View File
@@ -1,4 +1,5 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:livekit_client/src/track/audio_track.dart';
import '../proto/livekit_models.pb.dart';
import '../signal_client.dart';
import '../track/remote_track_publication.dart';
@@ -49,7 +50,9 @@ class RemoteParticipant extends Participant {
Track? track;
if (pub.kind == TrackType.AUDIO) {
track = new Track(pub.kind, pub.name, mediaTrack);
var audioTrack = new AudioTrack(pub.name, mediaTrack, stream);
audioTrack.start();
track = audioTrack;
} else if (pub.kind == TrackType.VIDEO) {
track = new VideoTrack(pub.name, mediaTrack, stream);
} else {
+3 -3
View File
@@ -55,7 +55,7 @@ class SignalClient {
Future<void> join(String url, String token, JoinOptions? options) async {
var rtcUrl = '$url/rtc';
var params = _paramsForToken(token);
var params = _joinParams(token);
if (options != null && options.autoSubscribe != null) {
params += '&auto_subscribe=${options.autoSubscribe! ? '1' : '0'}';
}
@@ -88,7 +88,7 @@ class SignalClient {
_ws = null;
url += '/rtc';
var params = _paramsForToken(token);
var params = _joinParams(token);
params += '&reconnect=1';
var uri = Uri.parse(url + params);
@@ -239,7 +239,7 @@ class SignalClient {
}
}
String _paramsForToken(String token) {
String _joinParams(String token) {
return '?access_token=$token&protocol=$protocolVersion';
}
+9
View File
@@ -0,0 +1,9 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
void startAudio(String id, MediaStreamTrack stream) {
// do nothing
}
void stopAudio(String id) {
// do nothing
}
+53
View File
@@ -0,0 +1,53 @@
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:flutter_webrtc/flutter_webrtc.dart';
// ignore: implementation_imports
import 'package:flutter_webrtc/src/web/media_stream_track_impl.dart';
const audioContainerId = 'livekit_audio_container';
const audioPrefix = 'livekit_audio_';
void startAudio(String id, MediaStreamTrack track) {
if (!(track is MediaStreamTrackWeb)) {
return;
}
var elementId = audioPrefix + id;
var audioElement = html.document.getElementById(elementId);
if (audioElement == null) {
audioElement = html.AudioElement()
..id = elementId
..autoplay = true;
findOrCreateAudioContainer().append(audioElement);
}
if (!(audioElement is html.AudioElement)) {
return;
}
var audioStream = html.MediaStream();
audioStream.addTrack(track.jsTrack);
audioElement.srcObject = audioStream;
}
void stopAudio(String id) {
var audioElement = html.document.getElementById(audioPrefix + id);
if (audioElement != null) {
if (audioElement is html.AudioElement) {
audioElement.srcObject = null;
}
audioElement.remove();
}
}
html.DivElement findOrCreateAudioContainer() {
var div = html.document.getElementById(audioContainerId);
if (div != null) {
return div as html.DivElement;
}
div = html.DivElement();
div.id = audioContainerId;
div.style.display = 'none';
html.document.body?.append(div);
return div as html.DivElement;
}
+27
View File
@@ -0,0 +1,27 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import '../proto/livekit_models.pbenum.dart';
import 'local_audio_track.dart';
import 'track.dart';
import '_audio_api.dart' if (dart.library.html) '_audio_html.dart' as audio;
class AudioTrack extends Track {
MediaStream? mediaStream;
AudioTrack(String name, MediaStreamTrack track, this.mediaStream)
: super(TrackType.AUDIO, name, track);
start() {
if (!(this is LocalAudioTrack)) {
audio.startAudio(getCid(), mediaTrack);
}
}
@override
stop() {
mediaStream?.dispose();
mediaStream = null;
audio.stopAudio(getCid());
super.stop();
}
}
+4 -14
View File
@@ -1,15 +1,12 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:livekit_client/src/track/audio_track.dart';
import '../errors.dart';
import '../proto/livekit_models.pb.dart';
import 'options.dart';
import 'track.dart';
class LocalAudioTrack extends Track {
MediaStream? mediaStream;
LocalAudioTrack(String name, MediaStreamTrack track, this.mediaStream)
: super(TrackType.AUDIO, name, track);
class LocalAudioTrack extends AudioTrack {
LocalAudioTrack(String name, MediaStreamTrack track, MediaStream stream)
: super(name, track, stream);
static Future<LocalAudioTrack> createTrack(
[LocalAudioTrackOptions? options]) async {
@@ -28,11 +25,4 @@ class LocalAudioTrack extends Track {
return Future.error(e);
}
}
@override
stop() {
super.stop();
mediaStream?.dispose();
mediaStream = null;
}
}