Skip to content

Expose an event stream for input device changes (add/remove) instead of polling listInputDevices() #618

Description

@Ranjan-Bhagat

Is your feature request related to a problem? Please describe.

listInputDevices() is a one-shot query, so an app showing a microphone picker has no way to learn that a device was plugged in or removed while the picker is on screen. The only workaround today is polling listInputDevices() on a timer and diffing the result, which burns a native enumeration every interval and still adds seconds of latency. All desktop OSes expose push notifications for this (IMMNotificationClient on Windows, CoreAudio property listeners on macOS, navigator.mediaDevices.ondevicechange on web), but the plugin does not surface them.

Describe the solution you'd like

A broadcast stream on AudioRecorder that fires when the set of input devices changes, e.g.:

/// Emits whenever an input device is added or removed.
/// Platforms without native support emit nothing.
Stream<List<InputDevice>> get onInputDevicesChanged;

(or a plain Stream<void> signal, with callers re-running listInputDevices() themselves, if you prefer to keep the contract minimal.)

Sketch of the implementation, reusing the event-channel machinery the plugin already has:

  • record_platform_interface: add the method with a default implementation returning an empty stream, so no platform is forced to support it.
  • record_windows: register an IMMNotificationClient on the IMMDeviceEnumerator, debounce the callback burst a physical plug event produces, and push through the existing event_stream_handler pattern.
  • record_macos: a CoreAudio property listener on kAudioHardwarePropertyDevices, same event-channel pattern.
  • record_web: wire navigator.mediaDevices.ondevicechange.
  • Android/iOS/Linux: left as follow-ups, inheriting the empty-stream default.

I'm happy to implement this and send a PR (Windows + web + platform interface first) if you're open to the feature. Wanted to check the API shape with you before writing native code.

Describe alternatives you've considered

  • Polling listInputDevices() on a 2 s timer and diffing, which works but wastes enumerations and adds latency.
  • Adopting flutter_webrtc just for its ondevicechange event, which drags an entire WebRTC engine into the binary for what is one OS callback.
  • A private platform channel in our app, which duplicates device plumbing the plugin already owns.

Additional context

Use case: a desktop dictation app (Flutter Windows/macOS/Linux) with a microphone picker in its settings page. Users plug in USB/Bluetooth headsets while the app is running and expect the picker to reflect it without restarting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions