Skip to content

Commit

Permalink
feat: provide option to skip stop/restartTrack for mute/unmute (#516)
Browse files Browse the repository at this point in the history
* feat: provide option to skip stop/restartTrack for mute/unmute

also fallsback to the default capture options for respective setSourceEnableds

* chore: skip mute/replaceTrack for firefox because .enabled works as expected
  • Loading branch information
td-famedly authored May 20, 2024
1 parent 4685806 commit 1d6ee2a
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 11 deletions.
13 changes: 11 additions & 2 deletions lib/src/core/room.dart
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,19 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
})
..on<SignalRemoteMuteTrackEvent>((event) async {
final publication = localParticipant?.trackPublications[event.sid];

final stopOnMute = switch (publication?.source) {
TrackSource.camera =>
roomOptions.defaultCameraCaptureOptions.stopCameraCaptureOnMute,
TrackSource.microphone =>
roomOptions.defaultAudioCaptureOptions.stopAudioCaptureOnMute,
_ => true,
};

if (event.muted) {
await publication?.mute();
await publication?.mute(stopOnMute: stopOnMute);
} else {
await publication?.unmute();
await publication?.unmute(stopOnMute: stopOnMute);
}
})
..on<SignalTrackUnpublishedEvent>((event) async {
Expand Down
15 changes: 13 additions & 2 deletions lib/src/participant/local.dart
Original file line number Diff line number Diff line change
Expand Up @@ -510,13 +510,15 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
/// Shortcut for publishing a [TrackSource.camera]
Future<LocalTrackPublication?> setCameraEnabled(bool enabled,
{CameraCaptureOptions? cameraCaptureOptions}) async {
cameraCaptureOptions ??= room.roomOptions.defaultCameraCaptureOptions;
return setSourceEnabled(TrackSource.camera, enabled,
cameraCaptureOptions: cameraCaptureOptions);
}

/// Shortcut for publishing a [TrackSource.microphone]
Future<LocalTrackPublication?> setMicrophoneEnabled(bool enabled,
{AudioCaptureOptions? audioCaptureOptions}) async {
audioCaptureOptions ??= room.roomOptions.defaultAudioCaptureOptions;
return setSourceEnabled(TrackSource.microphone, enabled,
audioCaptureOptions: audioCaptureOptions);
}
Expand All @@ -525,6 +527,8 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
Future<LocalTrackPublication?> setScreenShareEnabled(bool enabled,
{bool? captureScreenAudio,
ScreenShareCaptureOptions? screenShareCaptureOptions}) async {
screenShareCaptureOptions ??=
room.roomOptions.defaultScreenShareCaptureOptions;
return setSourceEnabled(TrackSource.screenShareVideo, enabled,
captureScreenAudio: captureScreenAudio,
screenShareCaptureOptions: screenShareCaptureOptions);
Expand All @@ -547,8 +551,15 @@ class LocalParticipant extends Participant<LocalTrackPublication> {

final publication = getTrackPublicationBySource(source);
if (publication != null) {
final stopOnMute = switch (publication.source) {
TrackSource.camera =>
cameraCaptureOptions?.stopCameraCaptureOnMute ?? true,
TrackSource.microphone =>
audioCaptureOptions?.stopAudioCaptureOnMute ?? true,
_ => true,
};
if (enabled) {
await publication.unmute();
await publication.unmute(stopOnMute: stopOnMute);
} else {
if (source == TrackSource.screenShareVideo) {
await removePublishedTrack(publication.sid);
Expand All @@ -558,7 +569,7 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
await removePublishedTrack(screenAudio.sid);
}
} else {
await publication.mute();
await publication.mute(stopOnMute: stopOnMute);
}
}
await room.applyAudioSpeakerSettings();
Expand Down
6 changes: 4 additions & 2 deletions lib/src/publication/local.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ class LocalTrackPublication<T extends LocalTrack> extends TrackPublication<T> {
}

/// Mute the track associated with this publication
Future<void> mute() async => await track?.mute();
Future<void> mute({bool stopOnMute = true}) async =>
await track?.mute(stopOnMute: stopOnMute);

/// Unmute the track associated with this publication
Future<void> unmute() async => await track?.unmute();
Future<void> unmute({bool stopOnMute = true}) async =>
await track?.unmute(stopOnMute: stopOnMute);

lk_rtc.TrackPublishedResponse toPBTrackPublishedResponse() =>
lk_rtc.TrackPublishedResponse(
Expand Down
7 changes: 7 additions & 0 deletions lib/src/support/platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ BrowserType lkBrowser() => lkBrowserImplementation();

BrowserVersion lkBrowserVersion() => lkBrowserVersionImplementation();

/// skips stop/replaceTrack for the following platforms and only toggles
/// track.enabled.
bool skipStopForTrackMute() =>
{PlatformType.windows}.contains(lkPlatform()) ||
(lkPlatformIs(PlatformType.web) &&
[BrowserType.firefox].contains(lkBrowser()));

enum PlatformType {
web,
windows,
Expand Down
8 changes: 4 additions & 4 deletions lib/src/track/local/local.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ abstract class LocalTrack extends Track {
/// Mutes this [LocalTrack]. This will stop the sending of track data
/// and notify the [RemoteParticipant] with [TrackMutedEvent].
/// Returns true if muted, false if unchanged.
Future<bool> mute() async {
Future<bool> mute({bool stopOnMute = true}) async {
logger.fine('LocalTrack.mute() muted: $muted');
if (muted) return false; // already muted
await disable();
if (!lkPlatformIs(PlatformType.windows)) {
if (!skipStopForTrackMute() && stopOnMute) {
await stop();
}
updateMuted(true, shouldSendSignal: true);
Expand All @@ -105,10 +105,10 @@ abstract class LocalTrack extends Track {
/// Un-mutes this [LocalTrack]. This will re-start the sending of track data
/// and notify the [RemoteParticipant] with [TrackUnmutedEvent].
/// Returns true if un-muted, false if unchanged.
Future<bool> unmute() async {
Future<bool> unmute({bool stopOnMute = true}) async {
logger.fine('LocalTrack.unmute() muted: $muted');
if (!muted) return false; // already un-muted
if (!lkPlatformIs(PlatformType.windows)) {
if (!skipStopForTrackMute() && stopOnMute) {
await restartTrack();
}
await enable();
Expand Down
18 changes: 17 additions & 1 deletion lib/src/track/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,24 @@ extension CameraPositionExt on CameraPosition {
class CameraCaptureOptions extends VideoCaptureOptions {
final CameraPosition cameraPosition;

/// set to false to only toggle enabled instead of stop/replaceTrack for muting
final bool stopCameraCaptureOnMute;

const CameraCaptureOptions({
this.cameraPosition = CameraPosition.front,
String? deviceId,
double? maxFrameRate,
VideoParameters params = VideoParametersPresets.h720_169,
}) : super(params: params, deviceId: deviceId, maxFrameRate: maxFrameRate);
this.stopCameraCaptureOnMute = true,
}) : super(
params: params,
deviceId: deviceId,
maxFrameRate: maxFrameRate,
);

CameraCaptureOptions.from({required VideoCaptureOptions captureOptions})
: cameraPosition = CameraPosition.front,
stopCameraCaptureOnMute = true,
super(
params: captureOptions.params,
deviceId: captureOptions.deviceId,
Expand Down Expand Up @@ -82,12 +91,15 @@ class CameraCaptureOptions extends VideoCaptureOptions {
CameraPosition? cameraPosition,
String? deviceId,
double? maxFrameRate,
bool? stopCameraCaptureOnMute,
}) =>
CameraCaptureOptions(
params: params ?? this.params,
cameraPosition: cameraPosition ?? this.cameraPosition,
deviceId: deviceId ?? this.deviceId,
maxFrameRate: maxFrameRate ?? this.maxFrameRate,
stopCameraCaptureOnMute:
stopCameraCaptureOnMute ?? this.stopCameraCaptureOnMute,
);
}

Expand Down Expand Up @@ -235,13 +247,17 @@ class AudioCaptureOptions extends LocalTrackOptions {
/// Defaults to true.
final bool typingNoiseDetection;

/// set to false to only toggle enabled instead of stop/replaceTrack for muting
final bool stopAudioCaptureOnMute;

const AudioCaptureOptions({
this.deviceId,
this.noiseSuppression = true,
this.echoCancellation = true,
this.autoGainControl = true,
this.highPassFilter = false,
this.typingNoiseDetection = true,
this.stopAudioCaptureOnMute = true,
});

@override
Expand Down

0 comments on commit 1d6ee2a

Please sign in to comment.