Capture client info (#71)
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
PODS:
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_webrtc (0.7.1):
|
||||
- Flutter
|
||||
@@ -15,6 +17,7 @@ PODS:
|
||||
- WebRTC-SDK (93.4577.01)
|
||||
|
||||
DEPENDENCIES:
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`)
|
||||
- livekit_client (from `.symlinks/plugins/livekit_client/ios`)
|
||||
@@ -27,6 +30,8 @@ SPEC REPOS:
|
||||
- WebRTC-SDK
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_webrtc:
|
||||
@@ -39,6 +44,7 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
flutter_webrtc: 611cab01a48b1d20e2b2409783c182134b8729e5
|
||||
Libyuv: 5f79ced0ee66e60a612ca97de1e6ccacd187a437
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import device_info_plus_macos
|
||||
import flutter_webrtc
|
||||
import livekit_client
|
||||
import path_provider_macos
|
||||
import shared_preferences_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
||||
LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
PODS:
|
||||
- device_info_plus_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
- flutter_webrtc (0.7.1):
|
||||
- FlutterMacOS
|
||||
- WebRTC-SDK (= 93.4577.01)
|
||||
@@ -13,6 +15,7 @@ PODS:
|
||||
- WebRTC-SDK (93.4577.01)
|
||||
|
||||
DEPENDENCIES:
|
||||
- device_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus_macos/macos`)
|
||||
- flutter_webrtc (from `Flutter/ephemeral/.symlinks/plugins/flutter_webrtc/macos`)
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/macos`)
|
||||
@@ -24,6 +27,8 @@ SPEC REPOS:
|
||||
- WebRTC-SDK
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
device_info_plus_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus_macos/macos
|
||||
flutter_webrtc:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/flutter_webrtc/macos
|
||||
FlutterMacOS:
|
||||
@@ -36,6 +41,7 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
device_info_plus_macos: 1ad388a1ef433505c4038e7dd9605aadd1e2e9c7
|
||||
flutter_webrtc: b5a65d35686e113195a2da282dfe11fa827c5e6b
|
||||
FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424
|
||||
livekit_client: d6920cc9a77586581b1109dd57a3b2b39d630e49
|
||||
|
||||
@@ -57,6 +57,48 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
device_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
device_info_plus_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
device_info_plus_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
device_info_plus_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
device_info_plus_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
eva_icons_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -296,6 +338,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
platform_detect:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform_detect
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -324,6 +373,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||
|
||||
// In order to *not* need this ignore, consider extracting the "web" version
|
||||
// of your plugin as a separate package, instead of inlining it in the same
|
||||
// package as the core of your plugin.
|
||||
// ignore: avoid_web_libraries_in_flutter
|
||||
// import 'dart:html' as html show window;
|
||||
|
||||
// ignore: unused_import
|
||||
import 'dart:html' as html show document, ScriptElement;
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||
|
||||
/// A web implementation of the Livekit plugin.
|
||||
class LiveKitWebPlugin {
|
||||
@@ -21,6 +20,13 @@ class LiveKitWebPlugin {
|
||||
|
||||
final pluginInstance = LiveKitWebPlugin();
|
||||
channel.setMethodCallHandler(pluginInstance.handleMethodCall);
|
||||
|
||||
// Unofficial method load js as flutter assets (unreliable)
|
||||
// html.document.head!.append(html.ScriptElement()
|
||||
// ..src = 'assets/packages/livekit_client/assets/ua-parser.min.js'
|
||||
// ..type = 'application/javascript'
|
||||
// ..defer = true
|
||||
// );
|
||||
}
|
||||
|
||||
/// Handles method calls over the MethodChannel of this plugin.
|
||||
|
||||
@@ -39,12 +39,14 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
|
||||
String token, {
|
||||
ConnectOptions? connectOptions,
|
||||
}) async {
|
||||
final rtcUri = Utils.buildUri(
|
||||
final rtcUri = await Utils.buildUri(
|
||||
uriString,
|
||||
token: token,
|
||||
connectOptions: connectOptions,
|
||||
);
|
||||
|
||||
logger.fine('SignalClient connecting with url: $rtcUri');
|
||||
|
||||
try {
|
||||
_ws = await LiveKitWebSocket.connect(
|
||||
rtcUri,
|
||||
@@ -56,7 +58,7 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
|
||||
);
|
||||
} catch (socketError) {
|
||||
// Re-build same uri for validate mode
|
||||
final validateUri = Utils.buildUri(
|
||||
final validateUri = await Utils.buildUri(
|
||||
uriString,
|
||||
token: token,
|
||||
connectOptions: connectOptions,
|
||||
@@ -90,7 +92,7 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
|
||||
await _ws?.dispose();
|
||||
_ws = null;
|
||||
|
||||
final rtcUri = Utils.buildUri(
|
||||
final rtcUri = await Utils.buildUri(
|
||||
uriString,
|
||||
token: token,
|
||||
reconnect: true,
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../logger.dart';
|
||||
import 'native_audio.dart';
|
||||
|
||||
// Method channel methods to call native code.
|
||||
class Native {
|
||||
@internal
|
||||
static const channel = MethodChannel('livekit_client');
|
||||
|
||||
@internal
|
||||
static Future<bool> configureAudio(
|
||||
NativeAudioConfiguration configuration) async {
|
||||
try {
|
||||
final result = await channel.invokeMethod<bool>(
|
||||
'configureNativeAudio',
|
||||
configuration.toMap(),
|
||||
);
|
||||
return result == true;
|
||||
} catch (error) {
|
||||
logger.warning('configureNativeAudio did throw $error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns OS's version as a string
|
||||
/// Currently only for iOS, macOS
|
||||
@internal
|
||||
static Future<String?> osVersionString() async {
|
||||
try {
|
||||
return await channel.invokeMethod<String>(
|
||||
'osVersionString',
|
||||
<String, dynamic>{},
|
||||
);
|
||||
} catch (error) {
|
||||
logger.warning('appleOSVersionString did throw error: ${error}');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
// https://developer.apple.com/documentation/avfaudio/avaudiosession/category
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../logger.dart';
|
||||
|
||||
enum AppleAudioCategory {
|
||||
soloAmbient,
|
||||
playback,
|
||||
@@ -109,19 +104,3 @@ class NativeAudioConfiguration {
|
||||
appleAudioMode: appleAudioMode ?? this.appleAudioMode,
|
||||
);
|
||||
}
|
||||
|
||||
const _lkMethodChannel = MethodChannel('livekit_client');
|
||||
|
||||
Future<bool> configureNativeAudio(
|
||||
NativeAudioConfiguration configuration) async {
|
||||
try {
|
||||
final result = await _lkMethodChannel.invokeMethod<bool>(
|
||||
'configureNativeAudio',
|
||||
configuration.toMap(),
|
||||
);
|
||||
return result == true;
|
||||
} catch (_) {
|
||||
logger.warning('configureAudioSession did throw $_');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,5 +8,6 @@ PlatformType lkPlatformImplementation() {
|
||||
if (Platform.isMacOS) return PlatformType.macOS;
|
||||
if (Platform.isLinux) return PlatformType.linux;
|
||||
if (Platform.isIOS) return PlatformType.iOS;
|
||||
return PlatformType.android;
|
||||
if (Platform.isAndroid) return PlatformType.android;
|
||||
throw UnsupportedError('Unknown Platform');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:synchronized/synchronized.dart' as sync;
|
||||
|
||||
import '../logger.dart';
|
||||
import '../support/native.dart';
|
||||
import '../support/native_audio.dart';
|
||||
import '../support/platform.dart';
|
||||
import 'local/audio.dart';
|
||||
@@ -83,7 +84,7 @@ mixin AudioManagementMixin on AudioTrack {
|
||||
logger.fine(
|
||||
'[$runtimeType] configuring for ${audioTrackState} using ${config}...');
|
||||
try {
|
||||
await configureNativeAudio(config);
|
||||
await Native.configureAudio(config);
|
||||
} catch (error) {
|
||||
logger.warning('[$runtimeType] Failed to configure ${error}');
|
||||
}
|
||||
|
||||
+92
-2
@@ -1,30 +1,103 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:platform_detect/platform_detect.dart' as pd;
|
||||
|
||||
import './proto/livekit_models.pb.dart' as lk_models;
|
||||
import './support/native.dart';
|
||||
import 'extensions.dart';
|
||||
import 'livekit.dart';
|
||||
import 'logger.dart';
|
||||
import 'options.dart';
|
||||
import 'support/platform.dart';
|
||||
import 'track/options.dart';
|
||||
import 'types.dart';
|
||||
|
||||
extension UriExt on Uri {
|
||||
@internal
|
||||
bool get isSecureScheme => ['https', 'wss'].contains(scheme);
|
||||
}
|
||||
|
||||
// Collection of state-less static methods
|
||||
class Utils {
|
||||
static Uri buildUri(
|
||||
// DeviceInfoPlugin caches internally
|
||||
static final _deviceInfoPlugin = DeviceInfoPlugin();
|
||||
|
||||
static Future<lk_models.ClientInfo?> _clientInfo() async {
|
||||
switch (lkPlatform()) {
|
||||
case PlatformType.web:
|
||||
return lk_models.ClientInfo(
|
||||
os: pd.operatingSystem.name.toLowerCase(),
|
||||
browser: pd.browser.name.toLowerCase(),
|
||||
browserVersion: pd.browser.version.canonicalizedVersion,
|
||||
);
|
||||
case PlatformType.windows:
|
||||
return lk_models.ClientInfo(
|
||||
os: 'windows',
|
||||
|
||||
/// [WindowsDeviceInfo] does not provide details...
|
||||
);
|
||||
|
||||
case PlatformType.macOS:
|
||||
final info = await _deviceInfoPlugin.macOsInfo;
|
||||
|
||||
/// [MacOsDeviceInfo.osRelease] returns Darwin version instead of macOS version
|
||||
/// So call native code to get os version
|
||||
String? osVersionString = await Native.osVersionString();
|
||||
|
||||
return lk_models.ClientInfo(
|
||||
os: 'macOS',
|
||||
osVersion: osVersionString,
|
||||
// Confirmed
|
||||
deviceModel: info.model,
|
||||
);
|
||||
|
||||
case PlatformType.android:
|
||||
final info = await _deviceInfoPlugin.androidInfo;
|
||||
return lk_models.ClientInfo(
|
||||
os: 'android',
|
||||
osVersion: info.version.release,
|
||||
deviceModel: info.model,
|
||||
);
|
||||
|
||||
case PlatformType.iOS:
|
||||
final info = await _deviceInfoPlugin.iosInfo;
|
||||
String? model = info.utsname.machine;
|
||||
if (model != null && ['i386', 'x86_64', 'arm64'].contains(model)) {
|
||||
model = 'iOSSimulator,${model}';
|
||||
}
|
||||
return lk_models.ClientInfo(
|
||||
os: 'iOS',
|
||||
// Confirmed
|
||||
osVersion: info.systemVersion,
|
||||
deviceModel: model,
|
||||
);
|
||||
|
||||
case PlatformType.linux:
|
||||
final info = await _deviceInfoPlugin.linuxInfo;
|
||||
return lk_models.ClientInfo(
|
||||
os: 'linux',
|
||||
osVersion: info.versionId,
|
||||
deviceModel: info.machineId,
|
||||
);
|
||||
|
||||
default:
|
||||
// case PlatformType.fuchsia:
|
||||
}
|
||||
}
|
||||
|
||||
@internal
|
||||
static Future<Uri> buildUri(
|
||||
String uriString, {
|
||||
required String token,
|
||||
ConnectOptions? connectOptions,
|
||||
bool reconnect = false,
|
||||
bool validate = false,
|
||||
bool forceSecure = false,
|
||||
}) {
|
||||
}) async {
|
||||
connectOptions ??= const ConnectOptions();
|
||||
|
||||
final Uri uri = Uri.parse(uriString);
|
||||
@@ -44,6 +117,8 @@ class Utils {
|
||||
}
|
||||
pathSegments.add(lastSegment);
|
||||
|
||||
final clientInfo = await _clientInfo();
|
||||
|
||||
return uri.replace(
|
||||
scheme: validate ? httpScheme : wsScheme,
|
||||
pathSegments: pathSegments,
|
||||
@@ -54,6 +129,16 @@ class Utils {
|
||||
'protocol': connectOptions.protocolVersion.toStringValue(),
|
||||
'sdk': 'flutter',
|
||||
'version': LiveKitClient.version,
|
||||
// client info
|
||||
if (clientInfo != null) ...{
|
||||
if (clientInfo.hasOs()) 'os': clientInfo.os,
|
||||
if (clientInfo.hasOsVersion()) 'os_version': clientInfo.osVersion,
|
||||
if (clientInfo.hasDeviceModel())
|
||||
'device_model': clientInfo.deviceModel,
|
||||
if (clientInfo.hasBrowser()) 'browser': clientInfo.browser,
|
||||
if (clientInfo.hasBrowserVersion())
|
||||
'browser_version': clientInfo.browserVersion,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -94,6 +179,7 @@ class Utils {
|
||||
|
||||
static final videoRids = ['q', 'h', 'f'];
|
||||
|
||||
@internal
|
||||
static List<rtc.RTCRtpEncoding> encodingsFromPresets(
|
||||
VideoDimensions dimensions, {
|
||||
required List<VideoParameters> presets,
|
||||
@@ -113,6 +199,7 @@ class Utils {
|
||||
return result;
|
||||
}
|
||||
|
||||
@internal
|
||||
static List<rtc.RTCRtpEncoding>? computeVideoEncodings({
|
||||
required bool isScreenShare,
|
||||
VideoDimensions? dimensions,
|
||||
@@ -173,6 +260,7 @@ class Utils {
|
||||
);
|
||||
}
|
||||
|
||||
@internal
|
||||
static List<lk_models.VideoLayer> computeVideoLayers(
|
||||
VideoDimensions dimensions,
|
||||
List<rtc.RTCRtpEncoding>? encodings,
|
||||
@@ -204,6 +292,7 @@ class Utils {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@internal
|
||||
static lk_models.VideoQuality? videoQualityForRid(String? rid) => {
|
||||
'f': lk_models.VideoQuality.HIGH,
|
||||
'h': lk_models.VideoQuality.MEDIUM,
|
||||
@@ -211,6 +300,7 @@ class Utils {
|
||||
}[rid];
|
||||
|
||||
// makes a debounce func, with 1 param
|
||||
@internal
|
||||
static Function(T) createDebounceFunc<T>(
|
||||
Function(T) f, {
|
||||
Function(Function)? cancelFunc,
|
||||
|
||||
+62
-6
@@ -64,6 +64,48 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
device_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
device_info_plus_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
device_info_plus_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0+1"
|
||||
device_info_plus_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
device_info_plus_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -211,28 +253,28 @@ packages:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "2.0.3"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -240,13 +282,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
platform_detect:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: platform_detect
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.1.2"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -261,6 +310,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@@ -356,7 +412,7 @@ packages:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
version: "2.3.4"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -24,6 +24,8 @@ dependencies:
|
||||
protobuf: ^2.0.1
|
||||
flutter_webrtc: ^0.8.1
|
||||
dart_webrtc: ^1.0.3
|
||||
device_info_plus: ^3.2.1
|
||||
platform_detect: ^2.0.3
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@@ -140,6 +140,22 @@ public class LiveKitPlugin: NSObject, FlutterPlugin {
|
||||
#endif
|
||||
}
|
||||
|
||||
private static let processInfo = ProcessInfo()
|
||||
|
||||
/// Returns os version as a string.
|
||||
/// format: `12.1`, `15.3.1`, `15.0.1`
|
||||
private static func osVersionString() -> String {
|
||||
let osVersion = processInfo.operatingSystemVersion
|
||||
var versions = [osVersion.majorVersion]
|
||||
if osVersion.minorVersion != 0 || osVersion.patchVersion != 0 {
|
||||
versions.append(osVersion.minorVersion)
|
||||
}
|
||||
if osVersion.patchVersion != 0 {
|
||||
versions.append(osVersion.patchVersion)
|
||||
}
|
||||
return versions.map({ String($0) }).joined(separator: ".")
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
|
||||
guard let args = call.arguments as? [String: Any?] else {
|
||||
@@ -151,6 +167,8 @@ public class LiveKitPlugin: NSObject, FlutterPlugin {
|
||||
switch call.method {
|
||||
case "configureNativeAudio":
|
||||
handleConfigureNativeAudio(args: args, result: result)
|
||||
case "osVersionString":
|
||||
result(LiveKitPlugin.osVersionString())
|
||||
default:
|
||||
print("[LiveKit] method not found: ", call.method)
|
||||
result(FlutterMethodNotImplemented)
|
||||
|
||||
Reference in New Issue
Block a user