import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_webrtc/flutter_webrtc.dart'; import '../track/local/audio.dart'; import '../track/local/video.dart'; import '../types/video_parameters.dart'; /// A type that represents front or back of the camera. enum CameraPosition { front, back, } /// Convenience extension for [CameraPosition]. extension CameraPositionExt on CameraPosition { /// Return a [CameraPosition] which front and back is switched. CameraPosition switched() => { CameraPosition.front: CameraPosition.back, CameraPosition.back: CameraPosition.front, }[this]!; } /// Options used when creating a [LocalVideoTrack] that captures the camera. class CameraCaptureOptions extends VideoCaptureOptions { final CameraPosition cameraPosition; const CameraCaptureOptions({ this.cameraPosition = CameraPosition.front, String? deviceId, double? maxFrameRate, VideoParameters params = VideoParametersPresets.h720_169, }) : super(params: params, deviceId: deviceId, maxFrameRate: maxFrameRate); CameraCaptureOptions.from({required VideoCaptureOptions captureOptions}) : cameraPosition = CameraPosition.front, super( params: captureOptions.params, deviceId: captureOptions.deviceId, maxFrameRate: captureOptions.maxFrameRate, ); @override Map toMediaConstraintsMap() { var constraints = { ...super.toMediaConstraintsMap(), 'facingMode': cameraPosition == CameraPosition.front ? 'user' : 'environment', }; if (deviceId != null) { if (kIsWeb) { constraints['deviceId'] = deviceId; } else { constraints['optional'] = [ {'sourceId': deviceId} ]; } } if (maxFrameRate != null) { constraints['frameRate'] = {'max': maxFrameRate}; } return constraints; } // Returns new options with updated properties CameraCaptureOptions copyWith({ VideoParameters? params, CameraPosition? cameraPosition, String? deviceId, double? maxFrameRate, }) => CameraCaptureOptions( params: params ?? this.params, cameraPosition: cameraPosition ?? this.cameraPosition, deviceId: deviceId ?? this.deviceId, maxFrameRate: maxFrameRate ?? this.maxFrameRate, ); } /// Options used when creating a [LocalVideoTrack] that captures the screen. class ScreenShareCaptureOptions extends VideoCaptureOptions { /// iOS only flag: Use Broadcast Extension for screen share capturing. /// See instructions on how to setup your Broadcast Extension here: /// https://github.com/flutter-webrtc/flutter-webrtc/wiki/iOS-Screen-Sharing#broadcast-extension-quick-setup final bool useiOSBroadcastExtension; final bool captureScreenAudio; const ScreenShareCaptureOptions({ this.useiOSBroadcastExtension = false, this.captureScreenAudio = false, String? sourceId, double? maxFrameRate, VideoParameters params = VideoParametersPresets.screenShareH1080FPS15, }) : super(params: params, deviceId: sourceId, maxFrameRate: maxFrameRate); ScreenShareCaptureOptions.from( {this.useiOSBroadcastExtension = false, this.captureScreenAudio = false, required VideoCaptureOptions captureOptions}) : super(params: captureOptions.params); ScreenShareCaptureOptions copyWith({ bool? captureScreenAudio, VideoParameters? params, String? sourceId, double? maxFrameRate, }) => ScreenShareCaptureOptions( captureScreenAudio: captureScreenAudio ?? this.captureScreenAudio, params: params ?? this.params, sourceId: sourceId ?? deviceId, maxFrameRate: maxFrameRate ?? this.maxFrameRate, ); @override Map toMediaConstraintsMap() { var constraints = super.toMediaConstraintsMap(); if (useiOSBroadcastExtension && WebRTC.platformIsIOS) { constraints['deviceId'] = 'broadcast'; } if (WebRTC.platformIsDesktop) { if (deviceId != null) { constraints['deviceId'] = {'exact': deviceId}; } if (maxFrameRate != 0.0) { constraints['mandatory'] = {'frameRate': maxFrameRate}; } } return constraints; } } /// Base class for track options. abstract class LocalTrackOptions { const LocalTrackOptions(); // All subclasses must be able to report constraints Map toMediaConstraintsMap(); } /// Base class for options when creating a [LocalVideoTrack]. abstract class VideoCaptureOptions extends LocalTrackOptions { // final LocalVideoTrackType type; final VideoParameters params; /// The deviceId of the capture device to use. /// Available deviceIds can be obtained through `flutter_webrtc`: ///
  /// import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
  ///
  /// List devices = await rtc.navigator.mediaDevices.enumerateDevices();
  /// // or
  /// List desktopSources = await rtc.desktopCapturer.getSources(types: [rtc.SourceType.Screen, rtc.SourceType.Window]);
  /// 
final String? deviceId; // Limit the maximum frameRate of the capture device. final double? maxFrameRate; const VideoCaptureOptions({ this.params = VideoParametersPresets.h540_169, this.deviceId, this.maxFrameRate, }); @override Map toMediaConstraintsMap() => params.toMediaConstraintsMap(); } /// Options used when creating a [LocalAudioTrack]. class AudioCaptureOptions extends LocalTrackOptions { /// The deviceId of the capture device to use. /// Available deviceIds can be obtained through `flutter_webrtc`: ///
  /// import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
  ///
  /// List devices = await rtc.navigator.mediaDevices.enumerateDevices();
  /// 
final String? deviceId; /// 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. final bool noiseSuppression; /// Attempt to use echoCancellation option (if supported by the platform) /// See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings/echoCancellation /// Defaults to true. final bool echoCancellation; /// Attempt to use autoGainControl option (if supported by the platform) /// See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/autoGainControl /// Defaults to true. final bool autoGainControl; /// Attempt to use highPassFilter options (if supported by the platform) /// Defaults to false. final bool highPassFilter; /// Attempt to use typingNoiseDetection option (if supported by the platform) /// Defaults to true. final bool typingNoiseDetection; const AudioCaptureOptions({ this.deviceId, this.noiseSuppression = true, this.echoCancellation = true, this.autoGainControl = true, this.highPassFilter = false, this.typingNoiseDetection = true, }); @override Map toMediaConstraintsMap() { var constraints = {}; /// in we platform it's not possible to provide optional and mandatory parameters. /// deviceId is a mandatory parameter if (!kIsWeb || (kIsWeb && deviceId == null)) { constraints['optional'] = >[ {'echoCancellation': echoCancellation}, {'googDAEchoCancellation': echoCancellation}, {'googEchoCancellation': echoCancellation}, {'googEchoCancellation2': echoCancellation}, {'noiseSuppression': noiseSuppression}, {'googNoiseSuppression': noiseSuppression}, {'googNoiseSuppression2': noiseSuppression}, {'googAutoGainControl': autoGainControl}, {'googHighpassFilter': highPassFilter}, {'googTypingNoiseDetection': typingNoiseDetection}, ]; } if (deviceId != null) { if (kIsWeb) { constraints['deviceId'] = deviceId; } else { constraints['optional'] .cast>() .add({'sourceId': deviceId}); } } return constraints; } AudioCaptureOptions copyWith({ String? deviceId, bool? noiseSuppression, bool? echoCancellation, bool? autoGainControl, bool? highPassFilter, bool? typingNoiseDetection, }) { return AudioCaptureOptions( deviceId: deviceId ?? this.deviceId, noiseSuppression: noiseSuppression ?? this.noiseSuppression, echoCancellation: echoCancellation ?? this.echoCancellation, autoGainControl: autoGainControl ?? this.autoGainControl, highPassFilter: highPassFilter ?? this.highPassFilter, typingNoiseDetection: typingNoiseDetection ?? this.typingNoiseDetection, ); } } class AudioOutputOptions { /// The deviceId of the output device to use. final String? deviceId; /// If true, the audio will be played on the speaker. /// for mobile only final bool? speakerOn; const AudioOutputOptions({this.deviceId, this.speakerOn}); AudioOutputOptions copyWith({String? deviceId, bool? speakerOn}) { return AudioOutputOptions( deviceId: deviceId ?? this.deviceId, speakerOn: speakerOn ?? this.speakerOn, ); } }