manually handle audio tracks for web
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user