Subscriber as primary (#8)

* Update protos

* Signal client

* Improve transport

* First implementation

* Fix publish

* Update `PCTransport` for debounce negotiation

* debounce func

* reconnect & events

* Update debounce func

* engine events

* make sure events don't emit after dispose

* prefix flutter_webrtc

* Cleaner `iceServers` update

* don't mutate user provided params

* fix tests

* event manager

* Fix: `Room.onDisconnected` gets fired multiple times

* data publish in example

* cleaner logic

* safer events

* un-prefix with LK

* organize imports

* Clean up

* remove `Tuple`

* `EventsEmitter` can now be directly listened to

`EventsEmitter` extends `EventsListenable`
This commit is contained in:
Hiroshi Horie
2021-09-18 00:10:16 +09:00
committed by GitHub
parent 50f56c5e1e
commit f4bd82a919
36 changed files with 1334 additions and 588 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
void startAudio(String id, MediaStreamTrack stream) {
void startAudio(String id, rtc.MediaStreamTrack stream) {
// do nothing
}
+2 -2
View File
@@ -1,14 +1,14 @@
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
// 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) {
void startAudio(String id, rtc.MediaStreamTrack track) {
if (track is! MediaStreamTrackWeb) {
return;
}
+3 -3
View File
@@ -1,4 +1,4 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import '../proto/livekit_models.pb.dart' as lk_models;
import '_audio_api.dart' if (dart.library.html) '_audio_html.dart' as audio;
@@ -6,9 +6,9 @@ import 'local_audio_track.dart';
import 'track.dart';
class AudioTrack extends Track {
MediaStream? mediaStream;
rtc.MediaStream? mediaStream;
AudioTrack(String name, MediaStreamTrack track, this.mediaStream)
AudioTrack(String name, rtc.MediaStreamTrack track, this.mediaStream)
: super(lk_models.TrackType.AUDIO, name, track);
/// Start playing audio track. On web platform, create an audio element and
+5 -5
View File
@@ -1,6 +1,6 @@
import 'dart:async';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import '../errors.dart';
import 'audio_track.dart';
@@ -9,19 +9,19 @@ import 'options.dart';
class LocalAudioTrack extends AudioTrack {
LocalAudioTrack(
String name,
MediaStreamTrack track,
MediaStream stream,
rtc.MediaStreamTrack track,
rtc.MediaStream stream,
) : super(name, track, stream);
/// Creates a new audio track from the default audio input device.
static Future<LocalAudioTrack> create([LocalAudioTrackOptions? options]) async {
// try {
final stream = await navigator.mediaDevices.getUserMedia(<String, dynamic>{
final stream = await rtc.navigator.mediaDevices.getUserMedia(<String, dynamic>{
'audio': true,
'video': false,
});
if (stream.getAudioTracks().isEmpty) throw TrackCreateError();
if (stream.getAudioTracks().isEmpty) throw TrackCreateException();
return LocalAudioTrack('', stream.getAudioTracks().first, stream);
}
+1 -2
View File
@@ -1,5 +1,4 @@
import 'package:livekit_client/src/logger.dart';
import '../logger.dart';
import '../participant/local_participant.dart';
import '../proto/livekit_models.pb.dart' as lk_models;
import 'track.dart';
+11 -11
View File
@@ -1,4 +1,4 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import '../errors.dart';
import '../logger.dart';
@@ -19,19 +19,19 @@ class LocalVideoTrack extends VideoTrack {
//
LocalVideoTrack._(
String name,
MediaStreamTrack mediaTrack,
MediaStream stream,
rtc.MediaStreamTrack mediaTrack,
rtc.MediaStream stream,
this.currentOptions,
) : super(name, mediaTrack, stream);
RTCRtpSender? get sender => transceiver?.sender;
rtc.RTCRtpSender? get sender => transceiver?.sender;
/// Restarts the track with new options. This is useful when switching between
/// front and back cameras.
Future<void> restartTrack([
LocalVideoTrackOptions? options,
]) async {
if (sender == null) throw TrackCreateError('could not restart track');
if (sender == null) throw TrackCreateException('could not restart track');
if (options != null && currentOptions.runtimeType != options.runtimeType) {
throw Exception('options must be a ${currentOptions.runtimeType}');
}
@@ -73,7 +73,7 @@ class LocalVideoTrack extends VideoTrack {
);
}
static Future<MediaStream> _createStream(
static Future<rtc.MediaStream> _createStream(
LocalVideoTrackOptions options,
) async {
final constraints = <String, dynamic>{
@@ -81,15 +81,15 @@ class LocalVideoTrack extends VideoTrack {
'video': options.toMediaConstraintsMap(),
};
final MediaStream stream;
final rtc.MediaStream stream;
if (options is ScreenTrackOptions) {
stream = await navigator.mediaDevices.getDisplayMedia(constraints);
stream = await rtc.navigator.mediaDevices.getDisplayMedia(constraints);
} else {
// options is CameraVideoTrackOptions
stream = await navigator.mediaDevices.getUserMedia(constraints);
stream = await rtc.navigator.mediaDevices.getUserMedia(constraints);
}
if (stream.getVideoTracks().isEmpty) throw TrackCreateError();
if (stream.getVideoTracks().isEmpty) throw TrackCreateException();
return stream;
}
}
@@ -97,7 +97,7 @@ class LocalVideoTrack extends VideoTrack {
//
// Convenience extensions
//
extension LKLocalVideoTrackExt on LocalVideoTrack {
extension LocalVideoTrackExt on LocalVideoTrack {
// Calls restartTrack under the hood
Future<void> setCameraPosition(CameraPosition position) async {
final options = currentOptions;
+4 -4
View File
@@ -1,4 +1,4 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
enum LocalVideoTrackType {
camera,
@@ -10,7 +10,7 @@ enum CameraPosition {
back,
}
extension LKCameraPositionExt on CameraPosition {
extension CameraPositionExt on CameraPosition {
CameraPosition swap() => {
CameraPosition.front: CameraPosition.back,
CameraPosition.back: CameraPosition.front,
@@ -74,12 +74,12 @@ class VideoEncoding {
}
extension VideoEncodingExt on VideoEncoding {
RTCRtpEncoding toRTCRtpEncoding({
rtc.RTCRtpEncoding toRTCRtpEncoding({
String? rid,
double? scaleResolutionDownBy = 1.0,
int? numTemporalLayers,
}) =>
RTCRtpEncoding(
rtc.RTCRtpEncoding(
rid: rid,
scaleResolutionDownBy: scaleResolutionDownBy,
maxFramerate: maxFramerate,
+7 -7
View File
@@ -1,4 +1,4 @@
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import 'package:uuid/uuid.dart';
import '../proto/livekit_models.pb.dart' as lk_models;
@@ -17,24 +17,24 @@ class Track {
String name;
lk_models.TrackType kind;
MediaStreamTrack mediaStreamTrack;
rtc.MediaStreamTrack mediaStreamTrack;
String? sid;
RTCRtpTransceiver? transceiver;
rtc.RTCRtpTransceiver? transceiver;
String? _cid;
Track(this.kind, this.name, this.mediaStreamTrack);
bool get muted => mediaStreamTrack.muted == null ? false : mediaStreamTrack.muted!;
RTCRtpMediaType get mediaType {
rtc.RTCRtpMediaType get mediaType {
switch (kind) {
case lk_models.TrackType.AUDIO:
return RTCRtpMediaType.RTCRtpMediaTypeAudio;
return rtc.RTCRtpMediaType.RTCRtpMediaTypeAudio;
case lk_models.TrackType.VIDEO:
return RTCRtpMediaType.RTCRtpMediaTypeVideo;
return rtc.RTCRtpMediaType.RTCRtpMediaTypeVideo;
// this should never happen
default:
return RTCRtpMediaType.RTCRtpMediaTypeAudio;
return rtc.RTCRtpMediaType.RTCRtpMediaTypeAudio;
}
}
+5 -5
View File
@@ -1,17 +1,17 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import '../proto/livekit_models.pb.dart' as lk_models;
import 'track.dart';
/// A video track will notify when its mediaTrack has changed.
class VideoTrack extends Track with ChangeNotifier {
MediaStream _mediaStream;
rtc.MediaStream _mediaStream;
VideoTrack(
String name,
MediaStreamTrack mediaTrack,
rtc.MediaStreamTrack mediaTrack,
this._mediaStream,
) : super(
lk_models.TrackType.VIDEO,
@@ -19,11 +19,11 @@ class VideoTrack extends Track with ChangeNotifier {
mediaTrack,
);
MediaStream get mediaStream => _mediaStream;
rtc.MediaStream get mediaStream => _mediaStream;
/// internal use
/// {@nodoc}
void setMediaStream(MediaStream stream) {
void setMediaStream(rtc.MediaStream stream) {
_mediaStream = stream;
notifyListeners();
}