VideoDimensions instead of width height
This commit is contained in:
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user