Reuse transceivers (#24)
* protocol 4 * default to v4 * mediaStreamTrack.enabled * track start * private constructor * remote audio/video tracks * log sdp * organize imports
This commit is contained in:
@@ -40,6 +40,7 @@ extension ProtocolVersionExt on ProtocolVersion {
|
||||
String toStringValue() => {
|
||||
ProtocolVersion.protocol2: '2',
|
||||
ProtocolVersion.protocol3: '3',
|
||||
ProtocolVersion.protocol4: '4',
|
||||
}[this]!;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||
import 'package:livekit_client/src/track/remote_audio_track.dart';
|
||||
import 'package:livekit_client/src/track/remote_video_track.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
@@ -8,10 +10,8 @@ import '../logger.dart';
|
||||
import '../managers/event.dart';
|
||||
import '../proto/livekit_models.pb.dart' as lk_models;
|
||||
import '../signal_client.dart';
|
||||
import '../track/audio_track.dart';
|
||||
import '../track/remote_track_publication.dart';
|
||||
import '../track/track.dart';
|
||||
import '../track/video_track.dart';
|
||||
import '../types.dart';
|
||||
import 'participant.dart';
|
||||
|
||||
@@ -91,14 +91,14 @@ class RemoteParticipant extends Participant {
|
||||
final Track track;
|
||||
if (pub.kind == lk_models.TrackType.AUDIO) {
|
||||
// audio track
|
||||
final audioTrack = AudioTrack(pub.name, mediaTrack, stream);
|
||||
await audioTrack.start();
|
||||
track = audioTrack;
|
||||
track = RemoteAudioTrack(pub.name, mediaTrack, stream);
|
||||
} else {
|
||||
// video track
|
||||
track = VideoTrack(pub.name, mediaTrack, stream);
|
||||
track = RemoteVideoTrack(pub.name, mediaTrack, stream);
|
||||
}
|
||||
|
||||
await track.start();
|
||||
|
||||
pub.track = track;
|
||||
addTrackPublication(pub);
|
||||
|
||||
|
||||
@@ -495,6 +495,7 @@ class RTCEngine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
|
||||
logger.fine('[$objectId] Received server offer(type: ${event.sd.type}, '
|
||||
'${subscriber!.pc.signalingState})');
|
||||
logger.finer('sdp: ${event.sd.sdp}');
|
||||
|
||||
await subscriber!.setRemoteDescription(event.sd);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
|
||||
LiveKitWebSocket? _ws;
|
||||
|
||||
SignalClient({
|
||||
this.protocol = ProtocolVersion.protocol3,
|
||||
this.protocol = ProtocolVersion.protocol4,
|
||||
}) {
|
||||
events.listen((event) {
|
||||
logger.fine('[SignalEvent] $event');
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:synchronized/synchronized.dart' as sync;
|
||||
import '../logger.dart';
|
||||
import '../proto/livekit_models.pb.dart' as lk_models;
|
||||
import '../support/native_audio.dart';
|
||||
import '_audio_api.dart' if (dart.library.html) '_audio_html.dart' as audio;
|
||||
|
||||
import 'local_audio_track.dart';
|
||||
import 'track.dart';
|
||||
|
||||
@@ -22,7 +22,7 @@ enum AudioTrackState {
|
||||
typedef ConfigureNativeAudioFunc = Future<NativeAudioConfiguration> Function(
|
||||
AudioTrackState state);
|
||||
|
||||
class AudioTrack extends Track {
|
||||
abstract class AudioTrack extends Track {
|
||||
// it's possible to set custom function here to customize audio session configuration
|
||||
static ConfigureNativeAudioFunc nativeAudioConfigurationForAudioTrackState =
|
||||
defaultNativeAudioConfigurationFunc;
|
||||
@@ -50,10 +50,6 @@ class AudioTrack extends Track {
|
||||
Future<bool> start() async {
|
||||
final didStart = await super.start();
|
||||
if (didStart) {
|
||||
if (this is! LocalAudioTrack) {
|
||||
audio.startAudio(getCid(), mediaStreamTrack);
|
||||
}
|
||||
|
||||
// update counter
|
||||
await _trackCounterLock.synchronized(() async {
|
||||
if (this is LocalAudioTrack) {
|
||||
@@ -64,7 +60,6 @@ class AudioTrack extends Track {
|
||||
await _onAudioTrackCountDidChange();
|
||||
});
|
||||
}
|
||||
|
||||
return didStart;
|
||||
}
|
||||
|
||||
@@ -72,10 +67,6 @@ class AudioTrack extends Track {
|
||||
Future<bool> stop() async {
|
||||
final didStop = await super.stop();
|
||||
if (didStop) {
|
||||
await mediaStream?.dispose();
|
||||
mediaStream = null;
|
||||
audio.stopAudio(getCid());
|
||||
|
||||
// update counter
|
||||
await _trackCounterLock.synchronized(() async {
|
||||
if (this is LocalAudioTrack) {
|
||||
@@ -86,7 +77,6 @@ class AudioTrack extends Track {
|
||||
await _onAudioTrackCountDidChange();
|
||||
});
|
||||
}
|
||||
|
||||
return didStop;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import 'audio_track.dart';
|
||||
import 'options.dart';
|
||||
|
||||
class LocalAudioTrack extends AudioTrack {
|
||||
LocalAudioTrack(
|
||||
// private constructor
|
||||
LocalAudioTrack._(
|
||||
String name,
|
||||
rtc.MediaStreamTrack track,
|
||||
rtc.MediaStream stream,
|
||||
@@ -29,6 +30,15 @@ class LocalAudioTrack extends AudioTrack {
|
||||
|
||||
if (stream.getAudioTracks().isEmpty) throw TrackCreateException();
|
||||
|
||||
return LocalAudioTrack('', stream.getAudioTracks().first, stream);
|
||||
return LocalAudioTrack._('', stream.getAudioTracks().first, stream);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> stop() async {
|
||||
final didStop = await super.stop();
|
||||
if (didStop) {
|
||||
await mediaStreamTrack.stop();
|
||||
}
|
||||
return didStop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,15 @@ class LocalVideoTrack extends VideoTrack {
|
||||
if (stream.getVideoTracks().isEmpty) throw TrackCreateException();
|
||||
return stream;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> stop() async {
|
||||
final didStop = await super.stop();
|
||||
if (didStop) {
|
||||
await mediaStreamTrack.stop();
|
||||
}
|
||||
return didStop;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||
import '_audio_api.dart' if (dart.library.html) '_audio_html.dart' as audio;
|
||||
import 'audio_track.dart';
|
||||
|
||||
class RemoteAudioTrack extends AudioTrack {
|
||||
//
|
||||
RemoteAudioTrack(
|
||||
String name,
|
||||
rtc.MediaStreamTrack track,
|
||||
rtc.MediaStream stream,
|
||||
) : super(name, track, stream);
|
||||
|
||||
@override
|
||||
Future<bool> start() async {
|
||||
final didStart = await super.start();
|
||||
if (didStart) {
|
||||
// web support
|
||||
audio.startAudio(getCid(), mediaStreamTrack);
|
||||
await enable();
|
||||
}
|
||||
return didStart;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> stop() async {
|
||||
final didStop = await super.stop();
|
||||
if (didStop) {
|
||||
// web support
|
||||
audio.stopAudio(getCid());
|
||||
await disable();
|
||||
}
|
||||
return didStop;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||
import 'package:livekit_client/src/track/video_track.dart';
|
||||
|
||||
class RemoteVideoTrack extends VideoTrack {
|
||||
//
|
||||
RemoteVideoTrack(
|
||||
String name,
|
||||
rtc.MediaStreamTrack mediaTrack,
|
||||
rtc.MediaStream stream,
|
||||
) : super(name, mediaTrack, stream);
|
||||
|
||||
@override
|
||||
Future<bool> start() async {
|
||||
final didStart = await super.start();
|
||||
if (didStart) {
|
||||
await enable();
|
||||
}
|
||||
return didStart;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> stop() async {
|
||||
final didStop = await super.stop();
|
||||
if (didStop) {
|
||||
await disable();
|
||||
}
|
||||
return didStop;
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,8 @@ abstract class Track extends DisposableChangeNotifier
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.fine('Track.start()');
|
||||
|
||||
_active = true;
|
||||
return true;
|
||||
}
|
||||
@@ -88,13 +90,29 @@ abstract class Track extends DisposableChangeNotifier
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
await mediaStreamTrack.stop();
|
||||
} catch (_) {
|
||||
logger.warning('[$objectId] rtc.mediaStreamTrack.stop() did throw ${_}');
|
||||
}
|
||||
logger.fine('Track.stop()');
|
||||
|
||||
_active = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> enable() async {
|
||||
logger.fine('Track.enable()');
|
||||
try {
|
||||
mediaStreamTrack.enabled = true;
|
||||
} catch (_) {
|
||||
logger.warning(
|
||||
'[$objectId] set rtc.mediaStreamTrack.enabled did throw ${_}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> disable() async {
|
||||
logger.fine('Track.disable()');
|
||||
try {
|
||||
mediaStreamTrack.enabled = false;
|
||||
} catch (_) {
|
||||
logger.warning(
|
||||
'[$objectId] set rtc.mediaStreamTrack.enabled did throw ${_}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ 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 {
|
||||
abstract class VideoTrack extends Track {
|
||||
rtc.MediaStream _mediaStream;
|
||||
|
||||
VideoTrack(
|
||||
|
||||
@@ -7,6 +7,7 @@ typedef CancelListenFunc = Function();
|
||||
enum ProtocolVersion {
|
||||
protocol2,
|
||||
protocol3,
|
||||
protocol4,
|
||||
}
|
||||
|
||||
enum ConnectionState {
|
||||
|
||||
Reference in New Issue
Block a user