organize video types

This commit is contained in:
Hiroshi Horie
2022-02-25 15:45:46 +09:00
parent 0dfbf03e5b
commit 0a339b6252
37 changed files with 427 additions and 515 deletions
+162
View File
@@ -0,0 +1,162 @@
import 'dart:math' as math;
import 'package:flutter/material.dart';
import '../extensions.dart';
import '../participant/participant.dart';
typedef CancelListenFunc = Function();
/// Protocol version to use when connecting to server.
/// Usually it's not recommended to change this.
enum ProtocolVersion {
v2,
v3, // Subscriber as primary
v4,
v5,
v6, // Session migration
}
/// Connection state type used throughout the SDK.
enum ConnectionState {
disconnected,
connecting,
reconnecting,
connected,
}
/// Connection quality between the [Participant] and server.
enum ConnectionQuality {
unknown,
poor,
good,
excellent,
}
/// Reliability used for publishing data through data channel.
enum Reliability {
reliable,
lossy,
}
enum TrackSource {
unknown,
camera,
microphone,
screenShareVideo,
screenShareAudio,
}
enum TrackSubscriptionState {
unsubscribed,
subscribed,
notAllowed,
}
/// The state of track data stream.
/// This is controlled by server to optimize bandwidth.
enum StreamState {
paused,
active,
}
enum DisconnectReason {
user,
peerConnection,
signal,
}
/// The reason why a track failed to publish.
enum TrackSubscribeFailReason {
invalidServerResponse,
notTrackMetadataFound,
unsupportedTrackType,
// ...
}
/// The iceTransportPolicy used for [RTCConfiguration].
/// See https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
enum RTCIceTransportPolicy {
all,
relay,
}
@immutable
class RTCConfiguration {
final int? iceCandidatePoolSize;
final List<RTCIceServer>? iceServers;
final RTCIceTransportPolicy? iceTransportPolicy;
const RTCConfiguration({
this.iceCandidatePoolSize,
this.iceServers,
this.iceTransportPolicy,
});
Map<String, dynamic> toMap() {
final iceServersMap = <Map<String, dynamic>>[
if (iceServers != null)
for (final e in iceServers!) e.toMap()
];
return <String, dynamic>{
// only supports unified plan
'sdpSemantics': 'unified-plan',
if (iceServersMap.isNotEmpty) 'iceServers': iceServersMap,
if (iceCandidatePoolSize != null)
'iceCandidatePoolSize': iceCandidatePoolSize,
if (iceTransportPolicy != null)
'iceTransportPolicy': iceTransportPolicy!.toStringValue(),
};
}
// Returns new options with updated properties
RTCConfiguration copyWith({
int? iceCandidatePoolSize,
List<RTCIceServer>? iceServers,
RTCIceTransportPolicy? iceTransportPolicy,
}) =>
RTCConfiguration(
iceCandidatePoolSize: iceCandidatePoolSize ?? this.iceCandidatePoolSize,
iceServers: iceServers ?? this.iceServers,
iceTransportPolicy: iceTransportPolicy ?? this.iceTransportPolicy,
);
}
@immutable
class RTCIceServer {
final List<String>? urls;
final String? username;
final String? credential;
const RTCIceServer({
this.urls,
this.username,
this.credential,
});
Map<String, dynamic> toMap() => <String, dynamic>{
if (urls?.isNotEmpty ?? false) 'urls': urls,
if (username?.isNotEmpty ?? false) 'username': username,
if (credential?.isNotEmpty ?? false) 'credential': credential,
};
}
@immutable
class ParticipantTrackPermission {
/// The participant id this permission applies to.
final String participantSid;
/// If set to true, the target participant can subscribe to all tracks from the local participant.
/// Takes precedence over [allowedTrackSids].
final bool allTracksAllowed;
/// The list of track ids that the target participant can subscribe to.
final List<String> allowedTrackSids;
const ParticipantTrackPermission(
this.participantSid,
this.allTracksAllowed,
this.allowedTrackSids,
);
}
+62
View File
@@ -0,0 +1,62 @@
import 'dart:math' as math;
import 'package:meta/meta.dart';
/// A simple class that represents dimensions of video.
@immutable
class VideoDimensions {
final int width;
final int height;
const VideoDimensions(
this.width,
this.height,
);
@override
String toString() => '${runtimeType}(${width}x${height})';
VideoDimensions copyWith({
int? width,
int? height,
}) =>
VideoDimensions(
width ?? this.width,
height ?? this.height,
);
}
extension VideoDimensionsHelpers on VideoDimensions {
/// Returns the larger value
int max() => math.max(width, height);
/// Returns the smaller value
int min() => math.min(width, height);
/// Simply returns the area
int area() => width * height;
}
extension VideoDimensionsPresets on VideoDimensions {
// 16:9 aspect ratio presets
static const h90_169 = VideoDimensions(160, 90);
static const h180_169 = VideoDimensions(320, 180);
static const h216_169 = VideoDimensions(384, 216);
static const h360_169 = VideoDimensions(640, 360);
static const h540_169 = VideoDimensions(960, 540);
static const h720_169 = VideoDimensions(1280, 720);
static const h1080_169 = VideoDimensions(1920, 1080);
static const h1440_169 = VideoDimensions(2560, 1440);
static const h2160_169 = VideoDimensions(3840, 2160);
// 4:3 aspect ratio presets
static const h120_43 = VideoDimensions(160, 120);
static const h180_43 = VideoDimensions(240, 180);
static const h240_43 = VideoDimensions(320, 240);
static const h360_43 = VideoDimensions(480, 360);
static const h480_43 = VideoDimensions(640, 480);
static const h540_43 = VideoDimensions(720, 540);
static const h720_43 = VideoDimensions(960, 720);
static const h1080_43 = VideoDimensions(1440, 1080);
static const h1440_43 = VideoDimensions(1920, 1440);
}
+34
View File
@@ -0,0 +1,34 @@
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import 'package:meta/meta.dart';
/// A type that represents video encoding information.
@immutable
class VideoEncoding {
final int maxFramerate;
final int maxBitrate;
const VideoEncoding({
required this.maxFramerate,
required this.maxBitrate,
});
@override
String toString() =>
'${runtimeType}(maxFramerate: ${maxFramerate}, maxBitrate: ${maxBitrate})';
}
/// Convenience extension for [VideoEncoding].
extension VideoEncodingExt on VideoEncoding {
rtc.RTCRtpEncoding toRTCRtpEncoding({
String? rid,
double? scaleResolutionDownBy = 1.0,
int? numTemporalLayers,
}) =>
rtc.RTCRtpEncoding(
rid: rid,
scaleResolutionDownBy: scaleResolutionDownBy,
maxFramerate: maxFramerate,
maxBitrate: maxBitrate,
numTemporalLayers: numTemporalLayers,
);
}
+258
View File
@@ -0,0 +1,258 @@
import 'package:meta/meta.dart';
import 'video_dimensions.dart';
import 'video_encoding.dart';
@immutable
class VideoParameters {
final String? description;
final VideoDimensions dimensions;
final VideoEncoding encoding;
const VideoParameters({
this.description,
required this.dimensions,
required this.encoding,
});
//
// TODO: Return constraints that will work for all platforms (Web & Mobile)
// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
//
Map<String, dynamic> toMediaConstraintsMap() => <String, dynamic>{
'width': dimensions.width,
'height': dimensions.height,
'frameRate': encoding.maxFramerate,
};
// Comparable
// @override
// int compareTo(VideoParameters other) {
// if (this.dimensions.area() == other.dimensions.area()) {
// return encoding.compare
// }
// }
}
extension VideoParametersPresets on VideoParameters {
// all 16:9 presets
static final List<VideoParameters> all169 = [
h90_169,
h180_169,
h216_169,
h360_169,
h540_169,
h720_169,
h1080_169,
h1440_169,
h2160_169,
];
// all 4:3 presets
static final List<VideoParameters> all43 = [
h120_43,
h180_43,
h240_43,
h360_43,
h480_43,
h540_43,
h720_43,
h1080_43,
h1440_43,
];
// all screen share presets
static final List<VideoParameters> allScreenShare = [
screenShareH360FPS3,
screenShareH720FPS5,
screenShareH720FPS15,
screenShareH1080FPS15,
screenShareH1080FPS30,
];
// 16:9 Presets
static const h90_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h90_169,
encoding: VideoEncoding(
maxBitrate: 60 * 1000,
maxFramerate: 15,
),
);
static const h180_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h180_169,
encoding: VideoEncoding(
maxBitrate: 120 * 1000,
maxFramerate: 15,
),
);
static const h216_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h216_169,
encoding: VideoEncoding(
maxBitrate: 180 * 1000,
maxFramerate: 15,
),
);
static const h360_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h360_169,
encoding: VideoEncoding(
maxBitrate: 300 * 1000,
maxFramerate: 20,
),
);
static const h540_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h540_169,
encoding: VideoEncoding(
maxBitrate: 600 * 1000,
maxFramerate: 25,
),
);
static const h720_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h720_169,
encoding: VideoEncoding(
maxBitrate: 2 * 1000 * 1000,
maxFramerate: 30,
),
);
static const h1080_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h1080_169,
encoding: VideoEncoding(
maxBitrate: 3 * 1000 * 1000,
maxFramerate: 30,
),
);
static const h1440_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h1440_169,
encoding: VideoEncoding(
maxBitrate: 5 * 1000 * 1000,
maxFramerate: 30,
),
);
static const h2160_169 = VideoParameters(
dimensions: VideoDimensionsPresets.h2160_169,
encoding: VideoEncoding(
maxBitrate: 8 * 1000 * 1000,
maxFramerate: 30,
),
);
// 4:3 presets
static const h120_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h120_43,
encoding: VideoEncoding(
maxBitrate: 80 * 1000,
maxFramerate: 15,
),
);
static const h180_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h180_43,
encoding: VideoEncoding(
maxBitrate: 100 * 1000,
maxFramerate: 15,
),
);
static const h240_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h240_43,
encoding: VideoEncoding(
maxBitrate: 150 * 1000,
maxFramerate: 15,
),
);
static const h360_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h360_43,
encoding: VideoEncoding(
maxBitrate: 225 * 1000,
maxFramerate: 20,
),
);
static const h480_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h480_43,
encoding: VideoEncoding(
maxBitrate: 300 * 1000,
maxFramerate: 20,
),
);
static const h540_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h540_43,
encoding: VideoEncoding(
maxBitrate: 450 * 1000,
maxFramerate: 25,
),
);
static const h720_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h720_43,
encoding: VideoEncoding(
maxBitrate: 1 * 500 * 1000,
maxFramerate: 30,
),
);
static const h1080_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h1080_43,
encoding: VideoEncoding(
maxBitrate: 2 * 500 * 1000,
maxFramerate: 30,
),
);
static const h1440_43 = VideoParameters(
dimensions: VideoDimensionsPresets.h1440_43,
encoding: VideoEncoding(
maxBitrate: 3 * 500 * 1000,
maxFramerate: 30,
),
);
// Screen share
static const screenShareH360FPS3 = VideoParameters(
dimensions: VideoDimensionsPresets.h360_169,
encoding: VideoEncoding(
maxBitrate: 200 * 1000,
maxFramerate: 3,
),
);
static const screenShareH720FPS5 = VideoParameters(
dimensions: VideoDimensionsPresets.h720_169,
encoding: VideoEncoding(
maxBitrate: 400 * 1000,
maxFramerate: 5,
),
);
static const screenShareH720FPS15 = VideoParameters(
dimensions: VideoDimensionsPresets.h720_169,
encoding: VideoEncoding(
maxBitrate: 1 * 1000 * 1000,
maxFramerate: 15,
),
);
static const screenShareH1080FPS15 = VideoParameters(
dimensions: VideoDimensionsPresets.h1080_169,
encoding: VideoEncoding(
maxBitrate: 1 * 500 * 1000,
maxFramerate: 15,
),
);
static const screenShareH1080FPS30 = VideoParameters(
dimensions: VideoDimensionsPresets.h1080_169,
encoding: VideoEncoding(
maxBitrate: 3 * 1000 * 1000,
maxFramerate: 30,
),
);
}