VideoDimensions instead of width height

This commit is contained in:
Hiroshi Horie
2021-12-13 21:49:42 +07:00
parent 3384bc6c6e
commit a82c5a7a50
7 changed files with 60 additions and 60 deletions
+6 -8
View File
@@ -101,8 +101,7 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
publishOptions ?? room.roomOptions?.defaultVideoPublishOptions;
// use constraints passed to getUserMedia by default
int width = track.currentOptions.params.width;
int height = track.currentOptions.params.height;
VideoDimensions dimensions = track.currentOptions.params.dimensions;
if (kIsWeb) {
// getSettings() is only implemented for Web
@@ -110,10 +109,10 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
// try to use getSettings for more accurate resolution
final settings = track.mediaStreamTrack.getSettings();
if (settings['width'] is int) {
width = settings['width'] as int;
dimensions = dimensions.copyWith(width: settings['width'] as int);
}
if (settings['height'] is int) {
height = settings['height'] as int;
dimensions = dimensions.copyWith(height: settings['height'] as int);
}
} catch (_) {
logger.warning('Failed to call `mediaStreamTrack.getSettings()`');
@@ -125,7 +124,7 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
name: track.name,
kind: track.kind,
source: track.source.toPBType(),
dimension: TrackDimension(width, height),
dimensions: dimensions,
);
logger.fine('publishVideoTrack addTrack response: ${trackInfo}');
@@ -133,12 +132,11 @@ class LocalParticipant extends Participant<LocalTrackPublication> {
await track.start();
logger.fine(
'Compute encodings with resolution: ${width}x${height}, options: ${publishOptions}');
'Compute encodings with resolution: ${dimensions}, options: ${publishOptions}');
// Video encodings and simulcasts
final encodings = Utils.computeVideoEncodings(
width: width,
height: height,
dimensions: dimensions,
options: publishOptions,
);
+2 -2
View File
@@ -32,7 +32,7 @@ abstract class TrackPublication<T extends Track> extends Disposable {
bool get muted => track?.muted ?? false;
bool simulcasted = false;
TrackDimension? dimension;
VideoDimensions? dimension;
bool get subscribed => track != null;
@@ -52,7 +52,7 @@ abstract class TrackPublication<T extends Track> extends Disposable {
void updateFromInfo(lk_models.TrackInfo info) {
simulcasted = info.simulcast;
if (info.type == lk_models.TrackType.VIDEO) {
dimension = TrackDimension(info.width, info.height);
dimension = VideoDimensions(info.width, info.height);
}
}
+2 -2
View File
@@ -147,7 +147,7 @@ class RTCEngine extends Disposable with EventsEmittable<EngineEvent> {
required String name,
required lk_models.TrackType kind,
required lk_models.TrackSource source,
TrackDimension? dimension,
VideoDimensions? dimensions,
bool? dtx,
}) async {
// TODO: Check if cid already published
@@ -158,7 +158,7 @@ class RTCEngine extends Disposable with EventsEmittable<EngineEvent> {
name: name,
type: kind,
source: source,
dimension: dimension,
dimensions: dimensions,
dtx: dtx,
);
+4 -4
View File
@@ -148,7 +148,7 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
required String name,
required lk_models.TrackType type,
required lk_models.TrackSource source,
TrackDimension? dimension,
VideoDimensions? dimensions,
bool? dtx,
}) {
final req = lk_rtc.AddTrackRequest(
@@ -158,10 +158,10 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
source: source,
);
if (type == lk_models.TrackType.VIDEO && dimension != null) {
if (type == lk_models.TrackType.VIDEO && dimensions != null) {
// video specific
req.width = dimension.width;
req.height = dimension.height;
req.width = dimensions.width;
req.height = dimensions.height;
}
if (type == lk_models.TrackType.AUDIO && dtx != null) {
+15 -26
View File
@@ -1,6 +1,7 @@
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
import '../track/local/video.dart';
import '../track/local/audio.dart';
import '../types.dart';
/// A type that represents front or back of the camera.
enum CameraPosition {
@@ -112,14 +113,12 @@ extension VideoEncodingExt on VideoEncoding {
class VideoParameters {
final String description;
final int width;
final int height;
final VideoDimensions dimensions;
final VideoEncoding encoding;
const VideoParameters({
required this.description,
required this.width,
required this.height,
required this.dimensions,
required this.encoding,
});
@@ -129,8 +128,7 @@ class VideoParameters {
static const presetQVGA169 = VideoParameters(
description: 'QVGA(320x180) 16:9',
width: 320,
height: 180,
dimensions: VideoDimensions(320, 180),
encoding: VideoEncoding(
maxBitrate: 125000,
maxFramerate: 15,
@@ -139,8 +137,7 @@ class VideoParameters {
static const presetVGA169 = VideoParameters(
description: 'VGA(640x360) 16:9',
width: 640,
height: 360,
dimensions: VideoDimensions(640, 360),
encoding: VideoEncoding(
maxBitrate: 400000,
maxFramerate: 30,
@@ -149,8 +146,7 @@ class VideoParameters {
static const presetQHD169 = VideoParameters(
description: 'QHD(960x540) 16:9',
width: 960,
height: 540,
dimensions: VideoDimensions(960, 540),
encoding: VideoEncoding(
maxBitrate: 800000,
maxFramerate: 30,
@@ -159,8 +155,7 @@ class VideoParameters {
static const presetHD169 = VideoParameters(
description: 'HD(1280x720) 16:9',
width: 1280,
height: 720,
dimensions: VideoDimensions(1280, 720),
encoding: VideoEncoding(
maxBitrate: 2500000,
maxFramerate: 30,
@@ -169,8 +164,7 @@ class VideoParameters {
static const presetFHD169 = VideoParameters(
description: 'FHD(1920x1080) 16:9',
width: 1920,
height: 1080,
dimensions: VideoDimensions(1920, 1080),
encoding: VideoEncoding(
maxBitrate: 4000000,
maxFramerate: 30,
@@ -179,8 +173,7 @@ class VideoParameters {
static const presetQVGA43 = VideoParameters(
description: 'QVGA(240x180) 4:3',
width: 240,
height: 180,
dimensions: VideoDimensions(240, 180),
encoding: VideoEncoding(
maxBitrate: 100000,
maxFramerate: 15,
@@ -189,8 +182,7 @@ class VideoParameters {
static const presetVGA43 = VideoParameters(
description: 'VGA(480x360) 4:3',
width: 480,
height: 360,
dimensions: VideoDimensions(480, 360),
encoding: VideoEncoding(
maxBitrate: 320000,
maxFramerate: 30,
@@ -199,8 +191,7 @@ class VideoParameters {
static const presetQHD43 = VideoParameters(
description: 'QHD(720x540) 4:3',
width: 720,
height: 540,
dimensions: VideoDimensions(720, 540),
encoding: VideoEncoding(
maxBitrate: 640000,
maxFramerate: 30,
@@ -209,8 +200,7 @@ class VideoParameters {
static const presetHD43 = VideoParameters(
description: 'HD(960x720) 4:3',
width: 960,
height: 720,
dimensions: VideoDimensions(960, 720),
encoding: VideoEncoding(
maxBitrate: 2000000,
maxFramerate: 30,
@@ -219,8 +209,7 @@ class VideoParameters {
static const presetFHD43 = VideoParameters(
description: 'FHD(1440x1080) 4:3',
width: 1440,
height: 1080,
dimensions: VideoDimensions(1440, 1080),
encoding: VideoEncoding(
maxBitrate: 3200000,
maxFramerate: 30,
@@ -248,8 +237,8 @@ class VideoParameters {
// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
//
Map<String, dynamic> toMediaConstraintsMap() => <String, dynamic>{
'width': width,
'height': height,
'width': dimensions.width,
'height': dimensions.height,
'frameRate': encoding.maxFramerate,
};
}
+18 -2
View File
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'extensions.dart';
import 'dart:math' as math;
typedef CancelListenFunc = Function();
@@ -134,12 +135,27 @@ class RTCIceServer {
}
@immutable
class TrackDimension {
class VideoDimensions {
final int width;
final int height;
const TrackDimension(
const VideoDimensions(
this.width,
this.height,
);
@override
String toString() => 'VideoDimensions(${width}×${height})';
/// Returns the larger value
int max() => math.max(width, height);
VideoDimensions copyWith({
int? width,
int? height,
}) =>
VideoDimensions(
width ?? this.width,
height ?? this.height,
);
}
+13 -16
View File
@@ -6,6 +6,7 @@ import 'extensions.dart';
import 'livekit.dart';
import 'options.dart';
import 'track/options.dart';
import 'types.dart';
extension UriExt on Uri {
bool get isSecureScheme => ['https', 'wss'].contains(scheme);
@@ -54,53 +55,49 @@ class Utils {
);
}
static List<VideoParameters> _presetsForResolution(
int width,
int height,
static List<VideoParameters> _presetsForDimensions(
VideoDimensions dimensions,
) {
final double aspect = width / height;
final double aspect = dimensions.width / dimensions.height;
if ((aspect - 16.0 / 9.0).abs() < (aspect - 4.0 / 3.0).abs()) {
return VideoParameters.presets169;
}
return VideoParameters.presets43;
}
static VideoParameters _findPresetForResolution(
int width,
int height, {
static VideoParameters _findPresetForDimensions(
VideoDimensions dimensions, {
required List<VideoParameters> presets,
}) {
assert(presets.isNotEmpty, 'presets should not be empty');
VideoParameters result = presets.first;
for (final preset in presets) {
if (width >= preset.width && height >= preset.height) result = preset;
if (dimensions.width >= preset.dimensions.width &&
dimensions.height >= preset.dimensions.height) result = preset;
}
return result;
}
static List<rtc.RTCRtpEncoding>? computeVideoEncodings({
int? width,
int? height,
VideoDimensions? dimensions,
VideoPublishOptions? options,
}) {
options ??= const VideoPublishOptions();
VideoEncoding? videoEncoding = options.videoEncoding;
if ((videoEncoding == null && !options.simulcast) ||
width == null ||
height == null) {
if ((videoEncoding == null && !options.simulcast) || dimensions == null) {
// don't set encoding when we are not simulcasting and user isn't restricting
// encoding parameters
return null;
}
final presets = _presetsForResolution(width, height);
final presets = _presetsForDimensions(dimensions);
if (videoEncoding == null) {
// find the right encoding based on width/height
final preset = _findPresetForResolution(width, height, presets: presets);
final preset = _findPresetForDimensions(dimensions, presets: presets);
// print('Using preset: ${preset.id}');
videoEncoding = preset.encoding;
// log.debug('using video encoding', videoEncoding);
@@ -118,7 +115,7 @@ class Utils {
),
// if resolution is high enough, we would send both h and q res..
// otherwise only send h
if (width >= 960) ...[
if (dimensions.max() >= 960) ...[
midPreset.encoding.toRTCRtpEncoding(
rid: 'h',
// passing decimals to hardware encoder of android devices