Telling the backend what the TV is
Telling the backend what the TV is
Section titled “Telling the backend what the TV is”Until this doc’s change the app reported a cast session exactly like local
playback. The only difference on the wire was Matomo’s ma_pn (ChromecastPlayer
/ AirPlayPlayer). Nothing said which receiver it was.
What exists, per technology
Section titled “What exists, per technology”Chromecast mDNS TXT record (CastDevice.extras) md model fn name ve firmware + RECEIVER_STATUS ca capabilities id uuid applications[0].displayNameAirPlay AVAudioSession current route (public) portName, uid (model / IP / manufacturer are private API: not used)DLNA not implemented in this appWhat leaves the phone
Section titled “What leaves the phone”One value object, PlaybackOutput (lib/domain/entities/playback_output.dart):
type chromecast | airplay (local sessions send nothing)model md Chromecast onlyfirmware ve Chromecast onlyreceiver_app receiver app displayName Chromecast onlyname friendly name bothdevice_key first 12 hex of SHA-256(salt | id or uid) bothNever sent: IP/host, MAC, raw Cast id, raw AirPlay uid, bs/ic/other TXT keys.
lib/core/utils/device_key.dart does the hashing; playback_output_mapper.dart
builds the object.
CastController / AirPlayController.playbackOutput │RemotePlaybackProgressReporter (the one place that sees session start/end) ├─ watch-history POST → "playback_output": {...} (optional field) ├─ Matomo ping + events → dimension4 = type, dimension5 = model └─ Marktag Play → metadata.playback_outputThe Hive progress queue stores the payload as built, so an offline retry keeps the output that was true when the minute was recorded.
Open items
Section titled “Open items”- The backend must accept the optional
playback_outputobject onPOST /v1/user/watch-historyand ignore it where unknown. The Postman collection is deliberately not updated until it does. - Matomo needs custom dimensions 4 and 5 configured for the site (action scope).
ca(capabilities bitmask) is parsed from TXT but not sent yet.