Option to control DTX (#25)
* protocol 4 * default to v4 * mediaStreamTrack.enabled * track start * private constructor * remote audio/video tracks * log sdp * organize imports * dtx option (default true)
This commit is contained in:
@@ -79,7 +79,7 @@ class _ConnectPageState extends State<ConnectPage> {
|
||||
_uriCtrl.text,
|
||||
_tokenCtrl.text,
|
||||
options: ConnectOptions(
|
||||
defaultPublishOptions: TrackPublishOptions(
|
||||
defaultVideoPublishOptions: VideoPublishOptions(
|
||||
simulcast: _simulcast,
|
||||
),
|
||||
),
|
||||
|
||||
+23
-5
@@ -6,23 +6,27 @@ class ConnectOptions {
|
||||
/// Auto-subscribe to room tracks upon connect, defaults to true.
|
||||
final bool autoSubscribe;
|
||||
|
||||
/// Default options used when publishing a track
|
||||
final TrackPublishOptions defaultPublishOptions;
|
||||
/// Default options used when publishing a video track
|
||||
final VideoPublishOptions defaultVideoPublishOptions;
|
||||
|
||||
/// Default options used when publishing a audio track
|
||||
final AudioPublishOptions defaultAudioPublishOptions;
|
||||
|
||||
const ConnectOptions({
|
||||
this.autoSubscribe = true,
|
||||
this.defaultPublishOptions = const TrackPublishOptions(),
|
||||
this.defaultVideoPublishOptions = const VideoPublishOptions(),
|
||||
this.defaultAudioPublishOptions = const AudioPublishOptions(),
|
||||
});
|
||||
}
|
||||
|
||||
class TrackPublishOptions {
|
||||
class VideoPublishOptions {
|
||||
///
|
||||
final VideoEncoding? videoEncoding;
|
||||
|
||||
///
|
||||
final bool simulcast;
|
||||
|
||||
const TrackPublishOptions({
|
||||
const VideoPublishOptions({
|
||||
this.videoEncoding,
|
||||
this.simulcast = false,
|
||||
});
|
||||
@@ -31,3 +35,17 @@ class TrackPublishOptions {
|
||||
String toString() =>
|
||||
'${runtimeType}(videoEncoding: ${videoEncoding}, simulcast: ${simulcast})';
|
||||
}
|
||||
|
||||
class AudioPublishOptions {
|
||||
/// DTX (Discontinuous Transmission)
|
||||
/// https://en.wikipedia.org/wiki/Discontinuous_transmission
|
||||
/// defaults to true
|
||||
final bool dtx;
|
||||
|
||||
const AudioPublishOptions({
|
||||
this.dtx = true,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => '${runtimeType}(dtx: ${dtx})';
|
||||
}
|
||||
|
||||
@@ -23,12 +23,15 @@ class LocalParticipant extends Participant {
|
||||
@internal
|
||||
final RTCEngine engine;
|
||||
@internal
|
||||
final TrackPublishOptions? defaultPublishOptions;
|
||||
final VideoPublishOptions? defaultVideoPublishOptions;
|
||||
@internal
|
||||
final AudioPublishOptions? defaultAudioPublishOptions;
|
||||
|
||||
LocalParticipant({
|
||||
required this.engine,
|
||||
required lk_models.ParticipantInfo info,
|
||||
this.defaultPublishOptions,
|
||||
this.defaultVideoPublishOptions,
|
||||
this.defaultAudioPublishOptions,
|
||||
required EventsEmitter<RoomEvent> roomEvents,
|
||||
}) : super(
|
||||
info.sid,
|
||||
@@ -39,16 +42,23 @@ class LocalParticipant extends Participant {
|
||||
}
|
||||
|
||||
/// publish an audio track to the room
|
||||
Future<TrackPublication> publishAudioTrack(LocalAudioTrack track) async {
|
||||
Future<TrackPublication> publishAudioTrack(
|
||||
LocalAudioTrack track, {
|
||||
AudioPublishOptions? options,
|
||||
}) async {
|
||||
if (audioTracks.any(
|
||||
(e) => e.track?.mediaStreamTrack.id == track.mediaStreamTrack.id)) {
|
||||
throw TrackPublishException('track already exists');
|
||||
}
|
||||
|
||||
// Use defaultPublishOptions if options is null
|
||||
options = options ?? defaultAudioPublishOptions;
|
||||
|
||||
final trackInfo = await engine.addTrack(
|
||||
cid: track.getCid(),
|
||||
name: track.name,
|
||||
kind: track.kind,
|
||||
dtx: options?.dtx,
|
||||
);
|
||||
|
||||
await track.start();
|
||||
@@ -73,15 +83,15 @@ class LocalParticipant extends Participant {
|
||||
/// Publish a video track to the room
|
||||
Future<TrackPublication> publishVideoTrack(
|
||||
LocalVideoTrack track, {
|
||||
TrackPublishOptions? options,
|
||||
VideoPublishOptions? options,
|
||||
}) async {
|
||||
if (videoTracks.any(
|
||||
(e) => e.track?.mediaStreamTrack.id == track.mediaStreamTrack.id)) {
|
||||
throw TrackPublishException('track already exists');
|
||||
}
|
||||
|
||||
// Use default options from `ConnectOptions` if options is null
|
||||
options = options ?? defaultPublishOptions;
|
||||
// Use defaultPublishOptions if options is null
|
||||
options = options ?? defaultVideoPublishOptions;
|
||||
|
||||
final trackInfo = await engine.addTrack(
|
||||
cid: track.getCid(),
|
||||
|
||||
+2
-1
@@ -75,7 +75,8 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
||||
localParticipant = LocalParticipant(
|
||||
engine: engine,
|
||||
info: joinResponse.participant,
|
||||
defaultPublishOptions: connectOptions?.defaultPublishOptions,
|
||||
defaultVideoPublishOptions: connectOptions?.defaultVideoPublishOptions,
|
||||
defaultAudioPublishOptions: connectOptions?.defaultAudioPublishOptions,
|
||||
roomEvents: events,
|
||||
);
|
||||
|
||||
|
||||
@@ -136,12 +136,18 @@ class RTCEngine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
required String name,
|
||||
required lk_models.TrackType kind,
|
||||
TrackDimension? dimension,
|
||||
bool? dtx,
|
||||
}) async {
|
||||
// TODO: Check if cid already published
|
||||
|
||||
// send request to add track
|
||||
signalClient.sendAddTrack(
|
||||
cid: cid, name: name, type: kind, dimension: dimension);
|
||||
cid: cid,
|
||||
name: name,
|
||||
type: kind,
|
||||
dimension: dimension,
|
||||
dtx: dtx,
|
||||
);
|
||||
|
||||
// wait for response, or timeout
|
||||
final event = await _signalListener.waitFor<SignalLocalTrackPublishedEvent>(
|
||||
|
||||
@@ -155,16 +155,25 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
|
||||
required String name,
|
||||
required lk_models.TrackType type,
|
||||
TrackDimension? dimension,
|
||||
bool? dtx,
|
||||
}) {
|
||||
final req = lk_rtc.AddTrackRequest(
|
||||
cid: cid,
|
||||
name: name,
|
||||
type: type,
|
||||
);
|
||||
if (dimension != null) {
|
||||
|
||||
if (type == lk_models.TrackType.VIDEO && dimension != null) {
|
||||
// video specific
|
||||
req.width = dimension.width;
|
||||
req.height = dimension.height;
|
||||
}
|
||||
|
||||
if (type == lk_models.TrackType.AUDIO && dtx != null) {
|
||||
// audio specific
|
||||
req.disableDtx = !dtx;
|
||||
}
|
||||
|
||||
_sendRequest(lk_rtc.SignalRequest(
|
||||
addTrack: req,
|
||||
));
|
||||
|
||||
+2
-2
@@ -83,9 +83,9 @@ class Utils {
|
||||
static List<rtc.RTCRtpEncoding>? computeVideoEncodings({
|
||||
int? width,
|
||||
int? height,
|
||||
TrackPublishOptions? options,
|
||||
VideoPublishOptions? options,
|
||||
}) {
|
||||
options ??= const TrackPublishOptions();
|
||||
options ??= const VideoPublishOptions();
|
||||
|
||||
VideoEncoding? videoEncoding = options.videoEncoding;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user