PackageTrack
Sign in Get early access

dart_cast

A pure Dart cross-platform casting package supporting Chromecast (CASTV2), AirPlay, and DLNA with built-in HTTP proxy for header injection.

0.7.4 3.4K downloads/mo #4399 most downloaded on pub.dev abdelaziz-mahdy/dart_cast

What this package is like to depend on

Last release 7 days ago

16 Aug 2026

Ships fairly regularly

a new release about every 5 weeks

Nearly every release is documented

notes for 14 of 14 stable releases

Nothing withdrawn

no release was ever pulled

5 months old

14 releases · first in 2026

14 releases in the last 12 months

see the full history below

Release timeline

14 releases · Mar 2026 to Aug 2026
Release Pre-release

Releases

latest 14
  1. 0.7.4 16 Aug 2026
    Release notes

    What's Changed

    • fix(chromecast): default subtitle honor, stale LOAD corpse attribution, resume track re-assert by @abdelaziz-mahdy in #19

    Full Changelog: v0.7.3...v0.7.4

    Open source →
    Release notes

    New

    • CastMedia.defaultSubtitle names the subtitle track playback starts with (matched by URL against subtitles). Honoured by Chromecast (activeTrackIds on LOAD) and DLNA (picked over subtitles.first)

    Fixed

    • Chromecast no longer activates the first subtitle track when none was chosen — the track-list order silently picked the on-screen language (a French-first list produced French subtitles regardless of what the app showed as selected). No defaultSubtitle now means no subtitle shown
    • Chromecast re-asserts the active subtitle after every pause → resume, including pauses from the TV remote. The Default Media Receiver can stop rendering cues after a pause/resume cycle while still reporting the track active; toggling the track set (deactivate + reactivate) re-attaches its renderer, which is what users were doing by hand
    • Chromecast LOAD retries are no longer failed by the previous attempt's dying receiver session. An unsolicited IDLE/ERROR broadcast from a session that neither answers the in-flight LOAD's requestId nor matches its session id is now ignored as a stale corpse (and its session deprecated). Observed live: a next-episode LOAD was declared failed 1ms after being sent — the corpse of the failed first attempt — while the receiver went on to play the episode fine, leaving the app convinced the old episode was still playing
    Open source →
  2. 0.7.3 25 Jul 2026
    Release notes

    Full Changelog: v0.7.2...v0.7.3

    Open source →
    Release notes

    New

    • MediaSource readers may now open asynchronously — an async function satisfies the reader, so sources backed by Android content:// URIs, network handles or a decrypt handshake no longer need a Stream.fromFuture(...) workaround (#12). Existing synchronous readers are unaffected; an async* reader needs a declared return type, which the MediaSource docs show
    Open source →
  3. 0.7.2 25 Jul 2026
    Release notes

    What's Changed

    • fix: offer AirPlay 1 to receivers that advertise both video versions by @abdelaziz-mahdy in #18

    Full Changelog: v0.7.1...v0.7.2

    Open source →
    Release notes

    Fixed

    • AirPlay: receivers advertising both AirPlay 1 and AirPlay 2 video (Apple TVs, the macOS receiver) now get one AirPlay 1 attempt if the AirPlay 2 /play returns 404. 0.7.0 sent every AirPlay 2 device down the V2 path and never offered V1, so a device implementing only the older endpoints could not play at all. The retry is gated on the device advertising bit 0 — it is not a return of the blind version probe 0.7.0 removed
    Open source →
  4. 0.7.1 25 Jul 2026
    Release notes

    Full Changelog: v0.7.0...v0.7.1

    Open source →
    Release notes

    Documentation only — no code changes.

    • AirPlay's status, the reason video fails on the receivers tested, and how to check your own device moved out of the README into doc/AIRPLAY.md
    • Protocol status is scoped to the devices actually tested rather than reading as a verdict on AirPlay itself; results from other hardware, an Apple TV especially, are welcome
    • The feature table distinguishes "implemented but blocked by the receiver" from "not built yet"
    Open source →
  5. 0.7.0 25 Jul 2026
    Release notes

    What's Changed

    • fix: report HLS duration and make seeking work on DLNA renderers by @abdelaziz-mahdy in #14
    • fix: make the AirPlay 2 video path real — capability-driven, transiently paired, with a timing server and /rate by @abdelaziz-mahdy in #13
    • fix: retry a DLNA SOAP action when the renderer drops the connection (#9) by @abdelaziz-mahdy in #15
    • feat: serve caller-supplied byte sources through the proxy (#12) by @abdelaziz-mahdy in #16
    • test: make the flaky-renderer mock respond once per connection by @abdelaziz-mahdy in #17

    Full Changelog: v0.6.0...v0.7.0

    Open source →
    Release notes

    AirPlay 2 and DLNA fixes plus caller-supplied byte sources, driven by testing against a TCL Google TV.

    Breaking

    • AirPlay selects its protocol version from the advertised feature bits instead of probing /play; devices with no video bit throw UnsupportedFeatureException immediately

    • AirPlaySession.connect() pairs with every AirPlay 2 receiver, so it can now throw NeedsPairingException where it previously returned a session. If you call connect() on an AirPlay 2 device and do not catch that exception, this release will start throwing at you. The old behaviour was not useful — the session it returned had fallen back to a legacy path those devices reject, so it could not cast anything — but it did not fail either. Handle it by prompting for the on-screen passcode and calling pairSetup(pin), or by catching it and offering Chromecast/DLNA instead:

      try {
        await session.connect();
      } on NeedsPairingException {
        // Show the code on the TV, then:
        await session.pairSetup(pinTheUserTyped);
        await session.connect();
      }
      

      Most smart TVs use PIN-less transient pairing and never reach this path; it is devices that demand a passcode which now surface it.

    • AirPlayMediaController.dispose() returns Future<void>; play() takes startPositionSeconds: instead of startPosition:

    Fixed

    • DLNA: seeking works when casting HLS — it previously stopped playback outright
    • DLNA: HLS casts report the real duration instead of one second
    • DLNA: a playback command no longer crashes with ClientException: Connection closed before full header was received when the renderer drops an idle connection — the action is retried once (#9)
    • DLNA: a renderer that accepts a connection then stalls fails after 10s instead of hanging the caller forever
    • DLNA: routine connection churn no longer floods the log with errors
    • AirPlay: AirPlay 2 receivers pair and establish a session correctly — PIN-less transient pairing, RTSP setup and keep-alive, all confirmed against a real TV. The package previously fell back to a legacy path these devices reject
    • AirPlay: failures report a cause instead of being swallowed — an unsupported device, a rejected handshake or a receiver-reported error now surfaces
    • AirPlay: further video-path corrections (protocol version selection, playback-state parsing, request ordering, startPosition). Unverified end to end — no receiver tested accepts a video URL, so nothing past the handshake can be exercised yet

    New

    • MediaSource + MediaProxy.registerSource() + CastMedia.source() — cast bytes the package cannot open itself: Android content:// URIs, Flutter assets, decrypted or in-memory content (#12). The application supplies a range-aware reader; the proxy handles HTTP, byte ranges and seeking. Works on Chromecast, DLNA and AirPlay, since it uses the same route local files already use
    • AirPlayTimingServer, transient pairing, PlaybackInfo.error
    • HlsParser.totalDuration / extractSegments, MediaProxy.probeHlsDuration / parseTimeSeekRange
    • tool/airplay_probe.dart, tool/airplay_hardware_check.dart, tool/dlna_hardware_check.dart, tool/chromecast_hardware_check.dart — hardware verification scripts

    Known limitations

    • AirPlay video does not play on the TV tested and cannot: that receiver exposes no /play endpoint, and Apple's own QuickTime fails on it identically — use Chromecast
    • DLNA sidecar subtitles did not render on the TV tested; embed SRT in MKV
    Open source →
  6. 0.6.0 29 May 2026
    Release notes

    What's Changed

    Full Changelog: v0.5.1...v0.6.0

    Open source →
    Release notes

    New

    • Alt-audio HLS sources (split video + audio) now play on Chromecast and DLNA — pure-Dart MPEG-TS remuxer combines them into one muxed stream
    • MediaProxy.registerAltAudioMuxed() — synthetic single-stream HLS master backed by per-segment muxing
    • HlsParser.extractAudioRenditions + audioGroup on extractVariants entries
    • TS DVB-table stripper for proxied video/mp2t, on by default; opt out via registerMedia(stripDvbTables: false)
    • MediaLoadFailedException from loadMedia() on LOAD_FAILED / IDLE+ERROR / 15s timeout, carrying the receiver-reported reason
    • HLS LOAD retries pass-through → muxer + stripper on failure, with requestId / mediaSessionId filtering against stale responses
    • ChromecastSession.enableReceiverDebugNamespaces (default false) — opt-in CaC + debugoverlay subscribe and verbose receiver logging for debugging

    Fixed

    • setSubtitle() activates the correct track (was always trackId=1)
    • CORS Access-Control-Allow-Origin echoes the receiver Origin when the LOAD includes a tracks array
    • State machine accepts loading → {buffering, paused, idle} and idle → {buffering, playing, paused}
    • DLNA: failed loadMedia returns to idle instead of stuck in loading
    • Content-Length only forwarded when the body streams through unchanged
    • Proxy segment / subtitle URLs end in .ts / .vtt for the Chromecast URL-extension probe
    • image/* Content-Type on proxied MPEG-TS subresources rewritten to video/mp2t
    Open source →
  7. 0.5.1 11 Apr 2026
    Release notes

    Patch release to reclaim the 10 pub points pana docked on 0.5.0's static-analysis check (40/50 → 50/50, total 160/160).

    No API, behavior, or dependency changes — pure lint cleanup under `lib/`.

    Fixed

    • `curly_braces_in_flow_control_structures` (×2) — wrap single-statement `if` bodies in braces in `ts_keyframe_scanner.dart` and `airplay/auth/airplay_auth.dart`.
    • `use_super_parameters` (×2) — the two `CastMessage_*` enum constructors in `chromecast/proto/cast_channel.dart` now use super-parameter syntax.
    • `camel_case_types` (×2) — suppressed via a file-level `// ignore_for_file` on `cast_channel.dart`, because the `CastMessage_ProtocolVersion` / `CastMessage_PayloadType` identifiers must stay byte-for-byte compatible with what `protoc --dart_out` emits for Chromium's `cast_channel.proto`.

    See #8 for the full diff and CLAUDE.md pre-PR checklist run used to verify.

    What's Changed

    • chore: fix remaining pana lints for 160/160 pub points (0.5.1) by @abdelaziz-mahdy in #8

    Full Changelog: v0.5.0...v0.5.1

    Open source →
    Release notes

    Fixed

    • Pub points (static analysis): Resolved the six pana lints under lib/ that kept the 0.5.0 static-analysis score at 40/50:
      • curly_braces_in_flow_control_structures in ts_keyframe_scanner.dart and airplay/auth/airplay_auth.dart — single-statement if bodies now wrapped in braces.
      • use_super_parameters on the two CastMessage_* enum constructors — converted to super-parameter syntax.
      • camel_case_types on the hand-written CastMessage_ProtocolVersion / CastMessage_PayloadType bindings in chromecast/proto/cast_channel.dart — suppressed via a file-level // ignore_for_file: camel_case_types, since these identifiers intentionally mirror the names protoc --dart_out would emit for Chromium's cast_channel.proto.
    Open source →
  8. 0.5.0 11 Apr 2026
    Release notes

    Closes #6.

    Changed

    • protobuf: Upgraded from ^3.1.0 to ^6.0.0 for the latest performance improvements and bug fixes from the protobuf.dart 4.0 → 6.0 releases. Hand-written CastMessage bindings use only stable GeneratedMessage / BuilderInfo / PbFieldType APIs, so no code changes were needed — CastMessage also lives under lib/src/ and is not re-exported, so the major bump does not leak into this package's public API.
    • Minimum Dart SDK: Bumped sdk constraint from ^3.0.0 to ^3.7.0 (required by protobuf 4.1.1+). The SDK bump also switches the default formatter to the Dart 3.7 tall style, so the lib/ and test/ tree was reformatted in this release.

    Fixed

    • Dropped two unnecessary ! non-null assertions in cast_service.dart and airplay/auth/airplay_auth.dart that a newer analyzer (pulled in by the SDK bump) started flagging as warnings.
    • example/: the Image.network errorBuilder signature now uses Dart 3.7 wildcard parameters ((_, _, _)) instead of multiple underscore names.

    Docs

    • Added CLAUDE.md with a pre-PR verification checklist that replays every CI step locally and calls out three gotchas that tripped this release (warning-level analyzer exits, formatter style flips on SDK bumps, and flutter analyze being stricter than dart analyze).

    What's Changed

    Full Changelog: v0.4.3...v0.5.0

    Open source →
    Release notes

    Changed

    • protobuf: Upgraded protobuf dependency from ^3.1.0 to ^6.0.0 for the latest performance improvements and bug fixes (#6). Hand-written CastMessage bindings remain compatible; no API changes.
    • Minimum Dart SDK: Bumped sdk constraint from ^3.0.0 to ^3.7.0 (required by protobuf 4.1.1+).
    Open source →
  9. 0.4.3 05 Apr 2026
    Release notes

    What's Changed

    Full Changelog: v0.4.2...v0.4.3

    Open source →
    Release notes

    Fixed

    • Analyzer warnings: Resolved pre-existing unused variable warnings in test files
    • Code formatting: Applied dart format to all source files
    Open source →
  10. 0.4.2 05 Apr 2026
    Release notes

    What's Changed

    New Contributors

    Full Changelog: v0.2.0...v0.4.2

    Open source →
    Release notes

    Fixed

    • Proxy IP selection: MediaProxy now picks the local interface on the same subnet as the target cast device, fixing casting failures on Android where the proxy would bind to a non-WiFi address unreachable by the cast device
    • Concurrent loadMedia guard: All protocol sessions (Chromecast, AirPlay, DLNA) now ignore duplicate loadMedia() calls while one is already in progress, preventing multiple LOAD messages from being sent to the device
    • Socket disconnect detection: Chromecast session now handles message stream errors and unexpected closures, transitioning to disconnected state so the app can react (previously the session stayed "connected" after a network drop)
    Open source →
  11. 0.4.1 21 Mar 2026
    Release notes

    Fixed

    • DLNA start position: seek now deferred until TV confirms PLAYING state (immediate seek was ignored by TVs still loading)
    • Chromecast subtitles for local files: subtitle files now served via HTTP/1.1 with CORS headers (HTTP/1.0 path lacked Access-Control-Allow-Origin required by Shaka Player)
    • Http10FileServer: returns 416 Range Not Satisfiable for invalid/out-of-bounds ranges
    • SubtitleConverter.vttToSrt(): uses targeted regex for timestamp dots (no longer corrupts non-timestamp content), expands 2-component MM:SS timestamps to HH:MM:SS
    • Removed stray response.close() after socket detach in synthetic content handler

    New

    • Updated example app with optimistic slider state, keyboard shortcuts, mute toggle, and responsive layout
    • Added protocol feature indicators in example device picker
    • Updated README with "What Works Where" feature matrix, protocol notes, and DLNA local files guide
    Open source →
  12. 0.3.1 19 Mar 2026
    Release notes
    • Added protocol status table to README with testing coverage and known limitations
    • Documented DLNA MP4 playback issues (TV-dependent, some reject proxy-served MP4)
    • Documented DLNA subtitle limitations (sec:CaptionInfoEx not universally supported)
    • Documented AirPlay video casting limitations (404 on some Google TV devices)
    • Recommended Chromecast as the primary tested protocol for local file casting
    Open source →
  13. 0.3.0 19 Mar 2026
    Release notes

    Breaking changes

    • DefaultMediaTransformer no longer wraps local TS files in HLS — it serves them directly via the proxy. Use TsHlsMediaTransformer or FfmpegMediaTransformer for Chromecast-compatible local TS casting.
    • CastMedia.useChunkedHls is deprecated and will be removed in a future release. TsHlsMediaTransformer always uses chunked HLS.
    • ChromecastSession now defaults to TsHlsMediaTransformer instead of DefaultMediaTransformer.

    New

    • TsHlsMediaTransformer — wraps local TS files in keyframe-aligned HLS playlists for Chromecast compatibility
    • MediaProxy.setPatPmt() / MediaProxy.setFirstPts() — enable correct PAT/PMT prepending and PTS offset for virtual HLS segments
    • FfmpegMediaTransformer reference implementation in example app — remuxes TS→MP4 via ffmpeg with progress callbacks and mobile platform support
    • doc/LOCAL_FILE_CASTING.md — comprehensive guide covering remux, HLS wrapping, and transcode approaches with tradeoffs

    Migration guide

    Replace direct DefaultMediaTransformer usage for local TS files:

    // Before (0.2.x) — DefaultMediaTransformer handled local TS→HLS internally
    final session = await device.connect();
    
    // After (0.3.0) — choose your transformer explicitly
    // Option A: FFmpeg remux (recommended)
    final session = await device.connect(
      mediaTransformer: FfmpegMediaTransformer(),
    );
    
    // Option B: Built-in HLS wrapping (no external tools)
    final session = await device.connect(
      mediaTransformer: TsHlsMediaTransformer(),
    );
    
    Open source →
  14. 0.2.0 17 Mar 2026
    Release notes
    • AirPlay feature flag detection via mDNS TXT records (AirPlayFeatures class parses features/ft bitmask)
    • AirPlayMediaController with V1/V2 /play format auto-negotiation (V1 binary plist → V1 text/parameters → V2 with RTSP SETUP)
    • UnsupportedFeatureException thrown immediately when a device lacks video support bits (0 and 49)
    • PlaybackException thrown when all /play format attempts are rejected by the device
    • Breaking: HapSession no longer has play, stop, scrub, or rate methods — use AirPlayMediaController instead
    • Added doc/PROTOCOL_REFERENCES.md with links to AirPlay, Chromecast, and DLNA specs
    • Added doc/FUTURE_WORK.md documenting AirPlay screen mirroring and RAOP audio streaming roadmap
    Open source →

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive