diff --git a/lib/src/options.dart b/lib/src/options.dart index 86d7437..40d09b0 100644 --- a/lib/src/options.dart +++ b/lib/src/options.dart @@ -1,3 +1,5 @@ +import 'track/local/audio.dart'; +import 'track/local/video.dart'; import 'track/options.dart'; import 'track/track.dart'; import 'publication/remote_track_publication.dart'; @@ -27,10 +29,19 @@ class ConnectOptions { /// Options used to modify the behavior of the [Room]. /// {@category Room} class RoomOptions { - /// Default options used when publishing a video track. + /// Default options used for [LocalVideoTrack.createCameraTrack]. + final CameraCaptureOptions defaultCameraCaptureOptions; + + /// Default options used for [LocalVideoTrack.createScreenShareTrack]. + final ScreenShareCaptureOptions defaultScreenShareCaptureOptions; + + /// Default options used when capturing video for a [LocalAudioTrack]. + final AudioCaptureOptions defaultAudioCaptureOptions; + + /// Default options used when publishing a [LocalVideoTrack]. final VideoPublishOptions defaultVideoPublishOptions; - /// Default options used when publishing a audio track. + /// Default options used when publishing a [LocalAudioTrack]. final AudioPublishOptions defaultAudioPublishOptions; /// When this is turned on, the following optimizations will be made: @@ -47,6 +58,9 @@ class RoomOptions { final bool stopLocalTrackOnUnpublish; const RoomOptions({ + this.defaultCameraCaptureOptions = const CameraCaptureOptions(), + this.defaultScreenShareCaptureOptions = const ScreenShareCaptureOptions(), + this.defaultAudioCaptureOptions = const AudioCaptureOptions(), this.defaultVideoPublishOptions = const VideoPublishOptions(), this.defaultAudioPublishOptions = const AudioPublishOptions(), this.optimizeVideo = true, diff --git a/lib/src/participant/local_participant.dart b/lib/src/participant/local_participant.dart index ff957f7..249e7d3 100644 --- a/lib/src/participant/local_participant.dart +++ b/lib/src/participant/local_participant.dart @@ -298,13 +298,16 @@ class LocalParticipant extends Participant { return publication; } else if (enabled) { if (source == TrackSource.camera) { - final track = await LocalVideoTrack.createCameraTrack(); + final track = await LocalVideoTrack.createCameraTrack( + room.roomOptions?.defaultCameraCaptureOptions); return await publishVideoTrack(track); } else if (source == TrackSource.microphone) { - final track = await LocalAudioTrack.create(); + final track = await LocalAudioTrack.create( + room.roomOptions?.defaultAudioCaptureOptions); return await publishAudioTrack(track); } else if (source == TrackSource.screenShareVideo) { - final track = await LocalVideoTrack.createScreenShareTrack(); + final track = await LocalVideoTrack.createScreenShareTrack( + room.roomOptions?.defaultScreenShareCaptureOptions); return await publishVideoTrack(track); } } diff --git a/lib/src/track/local.dart b/lib/src/track/local.dart index 3bbd5d0..1a67acf 100644 --- a/lib/src/track/local.dart +++ b/lib/src/track/local.dart @@ -86,16 +86,16 @@ abstract class LocalTrack extends Track { LocalTrackOptions options, ) async { final constraints = { - 'audio': options is LocalAudioTrackOptions + 'audio': options is AudioCaptureOptions ? options.toMediaConstraintsMap() : false, - 'video': options is LocalVideoTrackOptions + 'video': options is VideoCaptureOptions ? options.toMediaConstraintsMap() : false, }; final rtc.MediaStream stream; - if (options is ScreenShareTrackOptions) { + if (options is ScreenShareCaptureOptions) { stream = await rtc.navigator.mediaDevices.getDisplayMedia(constraints); } else { // options is CameraVideoTrackOptions @@ -103,10 +103,8 @@ abstract class LocalTrack extends Track { } // Check if the stream looks good - if ((options is LocalVideoTrackOptions && - stream.getVideoTracks().isEmpty) || - (options is LocalAudioTrackOptions && - stream.getAudioTracks().isEmpty)) { + if ((options is VideoCaptureOptions && stream.getVideoTracks().isEmpty) || + (options is AudioCaptureOptions && stream.getAudioTracks().isEmpty)) { throw TrackCreateException( 'Failed to create stream, at least 1 video or audio track should exist'); } diff --git a/lib/src/track/local/audio.dart b/lib/src/track/local/audio.dart index 26d2a9c..5132b7d 100644 --- a/lib/src/track/local/audio.dart +++ b/lib/src/track/local/audio.dart @@ -11,7 +11,7 @@ import '../options.dart'; class LocalAudioTrack extends LocalTrack with AudioTrack, AudioManagementMixin { // Options used for this track @override - covariant LocalAudioTrackOptions currentOptions; + covariant AudioCaptureOptions currentOptions; // private constructor LocalAudioTrack._( @@ -30,9 +30,9 @@ class LocalAudioTrack extends LocalTrack with AudioTrack, AudioManagementMixin { /// Creates a new audio track from the default audio input device. static Future create([ - LocalAudioTrackOptions? options, + AudioCaptureOptions? options, ]) async { - options ??= const LocalAudioTrackOptions(); + options ??= const AudioCaptureOptions(); final stream = await LocalTrack.createStream(options); return LocalAudioTrack._( diff --git a/lib/src/track/local/video.dart b/lib/src/track/local/video.dart index 5993d9d..fc0f97e 100644 --- a/lib/src/track/local/video.dart +++ b/lib/src/track/local/video.dart @@ -12,7 +12,7 @@ import '../track.dart'; class LocalVideoTrack extends LocalTrack with VideoTrack { // Options used for this track @override - covariant LocalVideoTrackOptions currentOptions; + covariant VideoCaptureOptions currentOptions; // Private constructor LocalVideoTrack._( @@ -31,9 +31,10 @@ class LocalVideoTrack extends LocalTrack with VideoTrack { /// Creates a LocalVideoTrack from camera input. static Future createCameraTrack([ - CameraTrackOptions? options, + CameraCaptureOptions? options, ]) async { - options ??= const CameraTrackOptions(); + options ??= const CameraCaptureOptions(); + final stream = await LocalTrack.createStream(options); return LocalVideoTrack._( Track.cameraName, @@ -49,9 +50,10 @@ class LocalVideoTrack extends LocalTrack with VideoTrack { /// Note: Android requires a foreground service to be started prior to /// creating a screen track. Refer to the example app for an implementation. static Future createScreenShareTrack([ - ScreenShareTrackOptions? options, + ScreenShareCaptureOptions? options, ]) async { - options ??= const ScreenShareTrackOptions(); + options ??= const ScreenShareCaptureOptions(); + final stream = await LocalTrack.createStream(options); return LocalVideoTrack._( Track.screenShareName, @@ -70,7 +72,7 @@ extension LocalVideoTrackExt on LocalVideoTrack { // Calls restartTrack under the hood Future setCameraPosition(CameraPosition position) async { final options = currentOptions; - if (options is! CameraTrackOptions) { + if (options is! CameraCaptureOptions) { logger.warning('Not a camera track'); return; } diff --git a/lib/src/track/options.dart b/lib/src/track/options.dart index 0e3140a..c10ce05 100644 --- a/lib/src/track/options.dart +++ b/lib/src/track/options.dart @@ -18,14 +18,18 @@ extension CameraPositionExt on CameraPosition { } /// Options used when creating a [LocalVideoTrack] that captures the camera. -class CameraTrackOptions extends LocalVideoTrackOptions { +class CameraCaptureOptions extends VideoCaptureOptions { final CameraPosition cameraPosition; - const CameraTrackOptions({ + const CameraCaptureOptions({ this.cameraPosition = CameraPosition.front, VideoParameters params = VideoParameters.presetQHD169, }) : super(params: params); + CameraCaptureOptions.from({required VideoCaptureOptions captureOptions}) + : cameraPosition = CameraPosition.front, + super(params: captureOptions.params); + @override Map toMediaConstraintsMap() => { ...super.toMediaConstraintsMap(), @@ -34,19 +38,24 @@ class CameraTrackOptions extends LocalVideoTrackOptions { }; // Returns new options with updated properties - CameraTrackOptions copyWith({ + CameraCaptureOptions copyWith({ VideoParameters? params, CameraPosition? cameraPosition, }) => - CameraTrackOptions( + CameraCaptureOptions( params: params ?? this.params, cameraPosition: cameraPosition ?? this.cameraPosition, ); } /// Options used when creating a [LocalVideoTrack] that captures the screen. -class ScreenShareTrackOptions extends LocalVideoTrackOptions { - const ScreenShareTrackOptions(); +class ScreenShareCaptureOptions extends VideoCaptureOptions { + const ScreenShareCaptureOptions({ + VideoParameters params = VideoParameters.presetHD169, + }) : super(params: params); + + ScreenShareCaptureOptions.from({required VideoCaptureOptions captureOptions}) + : super(params: captureOptions.params); } /// Base class for track options. @@ -57,11 +66,11 @@ abstract class LocalTrackOptions { } /// Base class for options when creating a [LocalVideoTrack]. -abstract class LocalVideoTrackOptions extends LocalTrackOptions { +abstract class VideoCaptureOptions extends LocalTrackOptions { // final LocalVideoTrackType type; final VideoParameters params; - const LocalVideoTrackOptions({ + const VideoCaptureOptions({ this.params = VideoParameters.presetQHD169, }); @@ -246,7 +255,7 @@ class VideoParameters { } /// Options used when creating a [LocalAudioTrack]. -class LocalAudioTrackOptions extends LocalTrackOptions { +class AudioCaptureOptions extends LocalTrackOptions { /// Attempt to use noiseSuppression option (if supported by the platform) /// See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings/noiseSuppression /// Defaults to true. @@ -270,7 +279,7 @@ class LocalAudioTrackOptions extends LocalTrackOptions { /// Defaults to true. final bool typingNoiseDetection; - const LocalAudioTrackOptions({ + const AudioCaptureOptions({ this.noiseSuppression = true, this.echoCancellation = true, this.autoGainControl = true,