blob: 8fa40bdc1bb843389fadb8bec283294891af3a57 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
/// Options used to create a camera with the given
/// [audio] and [video] media constraints.
///
/// These options represent web `MediaStreamConstraints`
/// and can be used to request the browser for media streams
/// with audio and video tracks containing the requested types of media.
///
/// https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints
@immutable
class CameraOptions {
/// Creates a new instance of [CameraOptions]
/// with the given [audio] and [video] constraints.
const CameraOptions({
AudioConstraints? audio,
VideoConstraints? video,
}) : audio = audio ?? const AudioConstraints(),
video = video ?? const VideoConstraints();
/// The audio constraints for the camera.
final AudioConstraints audio;
/// The video constraints for the camera.
final VideoConstraints video;
/// Converts the current instance to a Map.
Map<String, dynamic> toJson() {
return <String, Object>{
'audio': audio.toJson(),
'video': video.toJson(),
};
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
return other is CameraOptions &&
other.audio == audio &&
other.video == video;
}
@override
int get hashCode => hashValues(audio, video);
}
/// Indicates whether the audio track is requested.
///
/// By default, the audio track is not requested.
@immutable
class AudioConstraints {
/// Creates a new instance of [AudioConstraints]
/// with the given [enabled] constraint.
const AudioConstraints({this.enabled = false});
/// Whether the audio track should be enabled.
final bool enabled;
/// Converts the current instance to a Map.
Object toJson() => enabled;
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
return other is AudioConstraints && other.enabled == enabled;
}
@override
int get hashCode => enabled.hashCode;
}
/// Defines constraints that the video track must have
/// to be considered acceptable.
@immutable
class VideoConstraints {
/// Creates a new instance of [VideoConstraints]
/// with the given constraints.
const VideoConstraints({
this.facingMode,
this.width,
this.height,
this.deviceId,
});
/// The facing mode of the video track.
final FacingModeConstraint? facingMode;
/// The width of the video track.
final VideoSizeConstraint? width;
/// The height of the video track.
final VideoSizeConstraint? height;
/// The device id of the video track.
final String? deviceId;
/// Converts the current instance to a Map.
Object toJson() {
final Map<String, dynamic> json = <String, dynamic>{};
if (width != null) {
json['width'] = width!.toJson();
}
if (height != null) {
json['height'] = height!.toJson();
}
if (facingMode != null) {
json['facingMode'] = facingMode!.toJson();
}
if (deviceId != null) {
json['deviceId'] = <String, Object>{'exact': deviceId!};
}
return json;
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
return other is VideoConstraints &&
other.facingMode == facingMode &&
other.width == width &&
other.height == height &&
other.deviceId == deviceId;
}
@override
int get hashCode => hashValues(facingMode, width, height, deviceId);
}
/// The camera type used in [FacingModeConstraint].
///
/// Specifies whether the requested camera should be facing away
/// or toward the user.
class CameraType {
const CameraType._(this._type);
final String _type;
@override
String toString() => _type;
/// The camera is facing away from the user, viewing their environment.
/// This includes the back camera on a smartphone.
static const CameraType environment = CameraType._('environment');
/// The camera is facing toward the user.
/// This includes the front camera on a smartphone.
static const CameraType user = CameraType._('user');
}
/// Indicates the direction in which the desired camera should be pointing.
@immutable
class FacingModeConstraint {
/// Creates a new instance of [FacingModeConstraint]
/// with [ideal] constraint set to [type].
factory FacingModeConstraint(CameraType type) =>
FacingModeConstraint._(ideal: type);
/// Creates a new instance of [FacingModeConstraint]
/// with the given [ideal] and [exact] constraints.
const FacingModeConstraint._({this.ideal, this.exact});
/// Creates a new instance of [FacingModeConstraint]
/// with [exact] constraint set to [type].
factory FacingModeConstraint.exact(CameraType type) =>
FacingModeConstraint._(exact: type);
/// The ideal facing mode constraint.
///
/// If this constraint is used, then the camera would ideally have
/// the desired facing [type] but it may be considered optional.
final CameraType? ideal;
/// The exact facing mode constraint.
///
/// If this constraint is used, then the camera must have
/// the desired facing [type] to be considered acceptable.
final CameraType? exact;
/// Converts the current instance to a Map.
Object toJson() {
return <String, Object>{
if (ideal != null) 'ideal': ideal.toString(),
if (exact != null) 'exact': exact.toString(),
};
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
return other is FacingModeConstraint &&
other.ideal == ideal &&
other.exact == exact;
}
@override
int get hashCode => hashValues(ideal, exact);
}
/// The size of the requested video track used in
/// [VideoConstraints.width] and [VideoConstraints.height].
///
/// The obtained video track will have a size between [minimum] and [maximum]
/// with ideally a size of [ideal]. The size is determined by
/// the capabilities of the hardware and the other specified constraints.
@immutable
class VideoSizeConstraint {
/// Creates a new instance of [VideoSizeConstraint] with the given
/// [minimum], [ideal] and [maximum] constraints.
const VideoSizeConstraint({this.minimum, this.ideal, this.maximum});
/// The minimum video size.
final int? minimum;
/// The ideal video size.
///
/// The video would ideally have the [ideal] size
/// but it may be considered optional. If not possible
/// to satisfy, the size will be as close as possible
/// to [ideal].
final int? ideal;
/// The maximum video size.
final int? maximum;
/// Converts the current instance to a Map.
Object toJson() {
final Map<String, dynamic> json = <String, dynamic>{};
if (ideal != null) {
json['ideal'] = ideal;
}
if (minimum != null) {
json['min'] = minimum;
}
if (maximum != null) {
json['max'] = maximum;
}
return json;
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
return other is VideoSizeConstraint &&
other.minimum == minimum &&
other.ideal == ideal &&
other.maximum == maximum;
}
@override
int get hashCode => hashValues(minimum, ideal, maximum);
}