getMediaDevicesList function

Future<List<MediaDeviceInfo>> getMediaDevicesList(
  1. String kind
)

Retrieves a filtered list of media devices based on the specified kind.

This function attempts to get user media permissions before enumerating devices to ensure proper device labels and information are available.

Implementation

Future<List<MediaDeviceInfo>> getMediaDevicesList(String kind) async {
  try {
    // On macOS, first check if devices exist before requesting permissions
    // This prevents crashes when no audio/video devices are connected
    if (!kIsWeb && Platform.isMacOS) {
      try {
        final existingDevices = await navigator.mediaDevices.enumerateDevices();
        final hasRequestedKind = existingDevices.any((d) => d.kind == kind);
        if (!hasRequestedKind) {
          if (kDebugMode) {
            print('No $kind devices found on macOS - skipping getUserMedia');
          }
          return [];
        }
      } catch (e) {
        if (kDebugMode) {
          print('Could not enumerate devices on macOS: $e');
        }
        return [];
      }
    }

    // Attempt to get media stream to trigger permission prompt if needed
    // This ensures device labels are available
    try {
      final constraints = <String, dynamic>{};

      if (kind == 'videoinput') {
        constraints['video'] = true;
        constraints['audio'] = false;
      } else if (kind == 'audioinput') {
        constraints['audio'] = true;
        constraints['video'] = false;
      } else {
        // If kind is not recognized, try to get both
        constraints['audio'] = true;
        constraints['video'] = true;
      }

      // Get user media to trigger permission prompt
      try {
        MediaStream stream =
            await navigator.mediaDevices.getUserMedia(constraints);

        // Close the stream immediately as we don't need it
        for (var track in stream.getTracks()) {
          track.stop();
        }
      } catch (permissionError) {
        // Permission denied or not available, continue anyway
        // Devices may still be enumerated but with limited information
        if (kDebugMode) {
          print('Permission not granted for media devices: $permissionError');
        }
      }
    } catch (e) {
      // Continue even if getUserMedia fails
      if (kDebugMode) {
        print('Could not get user media: $e');
      }
    }

    // Enumerate all available media devices
    final devices = await navigator.mediaDevices.enumerateDevices();

    // Filter devices based on the specified kind
    final filtered = devices.where((device) => device.kind == kind).toList();

    return filtered;
  } catch (e) {
    // Return an empty list if an error occurs
    if (kDebugMode) {
      print('Error getting media devices list: $e');
    }
    return [];
  }
}