Skip to content

media: add MediaStreamTrack getSettings / onEnded / muted surface (W3C)#41

Merged
nus merged 1 commit into
mainfrom
mediastreamtrack-settings-events
Jun 8, 2026
Merged

media: add MediaStreamTrack getSettings / onEnded / muted surface (W3C)#41
nus merged 1 commit into
mainfrom
mediastreamtrack-settings-events

Conversation

@nus

@nus nus commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Partially addresses the W3C MediaStreamTrack gap from the RFC/W3C divergence audit — the read-only settings + lifecycle-event surface.

Problem

MediaStreamTrack was a bare interface: no getSettings(), no ended/mute/unmute events, and stop() was fire-and-forget.

Change

media_stream_track.dart:

  • MediaTrackSettings snapshot + getSettings() — base returns an empty snapshot; capture tracks override with real device values. Mirrors the existing flat MediaTrackConstraints shape.
  • onEnded (fires once), muted + onMute/onUnmute, with the event machinery + state on the abstract base so subclasses get them for free via notifyEnded() / setMuted() hooks. muted is the W3C source-driven state, distinct from the app-controlled enabled.

avf_capture_track.dart: macOS capture tracks fire onEnded from stop() and surface their configured deviceId/resolution/frameRate (video) or sampleRate/channelCount (audio).

Scope

The constraints surface (getCapabilities / getConstraints / applyConstraints) stays in BACKLOG — it requires reconfiguring the live capture source mid-stream, a much larger capture-backend change.

Tests

A real capture track is macOS-only (AVFoundation FFI), so the shared base behaviour is covered via an in-memory track (media_stream_track_test.dart): onEnded fires once + stop() idempotency, mute/unmute + muted-vs-enabled independence, and getSettings. dart analyze clean; full unit suite (650) passes. Reviewed with /simplify.

🤖 Generated with Claude Code

MediaStreamTrack was a bare interface — no getSettings(), no ended/mute
events, and stop() was fire-and-forget. Add the read-only W3C surface:

- `MediaTrackSettings` snapshot + `getSettings()` (base returns an empty
  snapshot; AVF capture tracks override with real device width/height/
  frameRate or sampleRate/channelCount + deviceId).
- `onEnded` (fires once), `muted` + `onMute`/`onUnmute`, with the event
  machinery + state living on the abstract base so subclasses get them
  for free via `notifyEnded()` / `setMuted()` hooks.
- AVF capture tracks fire `onEnded` from stop() and surface their
  settings.

The constraints surface (getCapabilities / getConstraints /
applyConstraints) stays in BACKLOG — it requires reconfiguring the live
capture source, a much larger capture-backend change.

Tested via an in-memory track (a real capture track is macOS-only):
onEnded once + stop idempotency, mute/unmute + muted-vs-enabled, and
getSettings. dart analyze clean; full unit suite passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nus nus merged commit 1b30f1e into main Jun 8, 2026
15 checks passed
@nus nus deleted the mediastreamtrack-settings-events branch June 8, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant