UPnPCast follows Semantic Versioning. Feature work is tracked here; bug fixes and doc updates land continuously. See CHANGELOG.md for what actually shipped.
- ✅ SSDP discovery hardened: dedicated listener thread,
SO_REUSEADDRbefore bind with ephemeral-port fallback,MulticastLockacquisition, device dedup by UDN - ✅ Coroutine-first public API (
DLNACastfacade over an instance-ownedCoreManagerengine) - ✅ Live playback state (
getPlaybackState), cached progress with interpolation, volume/mute control - ✅
CastOptions: external subtitles (incl. Samsung), MIME/UPnP class overrides, custom DIDL-Lite - ✅ Local file casting with built-in HTTP server (Range/seek, correct MIME types, typed errors)
- ✅ Test suite: 92 unit + protocol-level integration tests (in-process fake DLNA renderer)
- ✅ Internals: typed
RemoteDevice, unifiedUpnpHttpHTTP layer, pure-logic helpers
- GENA event subscription — subscribe to AVTransport events instead of polling, so remote play/pause/stop is pushed to the app (
StateVariablecallbacks) - Explicit
kotlinx-coroutines-androiddependency — currently arrives transitively via androidx core-ktx; declare it explicitly so consumers aren't exposed to version drift - Restore the Maven Central publishing pipeline (v1.2.0+ currently ships via JitPack only; Central has legacy 1.1.2)
- Playlist / queue support (multiple items, next/previous, SetNextAVTransportURI)
- Media browser support (ContentDirectory browsing of DLNA servers, not just renderers)
- Multi-device group casting
- Playback speed control (device-dependent)
- IPv6 SSDP support
- Demo app refresh to showcase
CastOptions,getPlaybackStateand the polling patterns
- No breaking public API changes within a minor version
- Coroutine-first: suspend functions, no callbacks
- Lightweight: no OkHttp/Gson; NanoHTTPD for local serving only
- Honest docs: examples in the README/FAQ must compile against the current release