90 lines
2.5 KiB
Dart
90 lines
2.5 KiB
Dart
import 'package:flutter/foundation.dart'
|
|
show TargetPlatform, defaultTargetPlatform, kIsWeb;
|
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
|
|
|
import '../utils/logger.dart';
|
|
|
|
class AudioInputDevice {
|
|
const AudioInputDevice({required this.id, required this.label});
|
|
|
|
final String id;
|
|
final String label;
|
|
}
|
|
|
|
class AudioDevices {
|
|
AudioDevices._();
|
|
|
|
static Future<List<AudioInputDevice>> microphones() async {
|
|
try {
|
|
final devices = await navigator.mediaDevices.enumerateDevices();
|
|
final mics = <AudioInputDevice>[];
|
|
final seen = <String>{};
|
|
for (final device in devices) {
|
|
if (device.kind != 'audioinput') continue;
|
|
if (device.deviceId.isEmpty || !seen.add(device.deviceId)) continue;
|
|
mics.add(
|
|
AudioInputDevice(id: device.deviceId, label: device.label.trim()),
|
|
);
|
|
}
|
|
return mics;
|
|
} catch (e) {
|
|
logger.w('[call] enumerateDevices: $e');
|
|
return const [];
|
|
}
|
|
}
|
|
|
|
static bool get switchesInsideEngine =>
|
|
!kIsWeb &&
|
|
(defaultTargetPlatform == TargetPlatform.android ||
|
|
defaultTargetPlatform == TargetPlatform.iOS ||
|
|
defaultTargetPlatform == TargetPlatform.macOS);
|
|
|
|
static Future<void> selectInput(String deviceId) async {
|
|
try {
|
|
await Helper.selectAudioInput(deviceId);
|
|
} catch (e) {
|
|
logger.w('[call] selectAudioInput($deviceId): $e');
|
|
}
|
|
}
|
|
|
|
static Object micConstraints(
|
|
String? deviceId, {
|
|
bool monitorCapture = false,
|
|
}) {
|
|
final constraints = <String, dynamic>{};
|
|
final hasDevice = deviceId != null && deviceId.isNotEmpty;
|
|
if (hasDevice && !switchesInsideEngine) {
|
|
if (kIsWeb) {
|
|
constraints['deviceId'] = deviceId;
|
|
} else {
|
|
constraints['optional'] = [
|
|
{'sourceId': deviceId},
|
|
];
|
|
}
|
|
}
|
|
if (monitorCapture) {
|
|
constraints['echoCancellation'] = true;
|
|
constraints['noiseSuppression'] = false;
|
|
constraints['autoGainControl'] = false;
|
|
constraints['highpassFilter'] = false;
|
|
}
|
|
return constraints.isEmpty ? true : constraints;
|
|
}
|
|
|
|
static Future<String?> findDevice(String token, {int attempts = 1}) async {
|
|
for (var attempt = 0; attempt < attempts; attempt++) {
|
|
for (final device in await microphones()) {
|
|
if (device.id == token ||
|
|
device.id.contains(token) ||
|
|
device.label.contains(token)) {
|
|
return device.id;
|
|
}
|
|
}
|
|
if (attempt + 1 < attempts) {
|
|
await Future<void>.delayed(const Duration(milliseconds: 250));
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|