← Engineering log
RobOS Smart TV Studio (packages/robos-tv) RobOS Movie Player (packages/movie-player) Tablo 4th Gen OTA DVR (192.168.1.55:8887) HMAC-MD5 LAN Auth & Broadcast Thumbnails 65" Roku OS SceneGraph & Live FFmpeg Transcoding

Tablo 4th Gen OTA DVR Integration: HMAC-MD5 LAN Discovery, Live & Recorded Broadcast Thumbnails, Desktop FFmpeg Transcoding, and 65" Roku TV Playback

RobOS Smart TV Studio (packages/robos-tv) and RobOS Movie Player (packages/movie-player) now integrate natively with Tablo 4th Gen Over-The-Air (OTA) DVR appliances (packages/robos-lib/tablo-client.js). Because Tablo provides no official Linux or desktop client and locks its port 8887 REST API behind per-request HMAC-MD5 cryptographic signatures while streaming raw ATSC MPEG-2 video and Dolby AC-3 audio, RobOS introduces a zero-cloud LAN client and dual-stream bridge on port 19210: real-time H.264/AAC fragmented-MP4 transcoding (/api/tablo/stream) for instant desktop playback (including active in-progress recordings like the 2026 World Series), automatic broadcast recording thumbnail acquisition with live ffmpeg frame fallback, and a dedicated 3rd top-level TABLO DVR tab on the 65" TCL Roku TV (192.168.1.15) with direct 60fps hardware HLS playback (/api/tablo/roku.m3u8).

RobOS TV and Movie Player Tablo 4th Gen OTA DVR and 65-inch Roku TV Technical Architecture
RobOS Tablo 4th Gen OTA DVR & 65" Roku TV architecture: packages/robos-lib/tablo-client.js signs REST calls to 192.168.1.55:8887 via HMAC-MD5, caches 16:9 broadcast snapshots (falling back to live ffmpeg -frames:v 1 capture for active recordings), and serves both browser-compatible H.264/AAC fMP4 streams and rewritten native Roku MPEG-2/AC-3 HLS playlists on port 19210.
flowchart LR
  subgraph Tablo["1. Tablo 4th Gen OTA DVR (192.168.1.55:8887)"]
REST["HMAC-MD5 Signed REST API
/server/info, /recordings/airings, /guide/channels"] IMG["Broadcast Image Server (/images/:id)
16:9 Recording Snapshots & Series Cover Art"] HLS["OTA Tuner HLS Server (:80/stream/pl.m3u8)
MPEG-2 Video + Dolby AC-3 Audio"] end subgraph Engine["2. RobOS Tablo & TV Engine (packages/robos-lib)"] TC["tablo-client.js
HMAC-MD5 Auth & Recording Catalog"] SNAP["Thumbnail Cache + Live Frame Fallback
~/.cache/robos/tablo-images/ + ffmpeg -frames:v 1"] PROXY["Dual Stream Bridge (:19210)
/api/tablo/stream (H.264/AAC fMP4) &
/api/tablo/roku.m3u8 (Native HLS Rewriter)"] end subgraph Desktop["3. Desktop Players"] STUDIO["RobOS Smart TV Studio (:19206)
Built-in HD Player & Commercial Skip (-15s/+30s/+5m)"] MPV["External MPV / VLC
Direct Zero-Transcode HLS"] end subgraph LivingRoom["4. 65-Inch TCL Roku TV (192.168.1.15:8060)"] ROKUTAB["Row 1 Top Image Tab: TABLO DVR (8)
+ 16:9 Broadcast Thumbnail Hero Frame"] ROKUVID["Native Roku SceneGraph Video Node
Direct 60fps MPEG-2 / AC-3 HLS Playback"] end REST --> TC IMG --> SNAP HLS --> SNAP HLS --> PROXY TC --> STUDIO TC --> ROKUTAB SNAP --> STUDIO SNAP --> ROKUTAB PROXY --> STUDIO HLS --> MPV PROXY --> ROKUVID
RobOS Smart TV Studio streaming an active in-progress Tablo DVR recording of the 2026 World Series on 47.1 WMSNFOX alongside 8 DVR recordings with broadcast thumbnails
RobOS Smart TV Studio — Live & Recorded Tablo OTA DVR: Streaming an active in-progress broadcast ([LIVE REC] 2026 World Series: Milwaukee Brewers at Tampa Bay Rays on 47.1 WMSNFOX) in the built-in HD player with commercial-skip controls (-15s, +30s, +5m), while displaying all 8 DVR recordings with acquired broadcast thumbnails on the right.
10-Foot Smart TV Cinema+ and Roku TV interface on the TABLO DVR (8) tab showing broadcast recording thumbnails, category cards, and live World Series spotlight
10-Foot Cinema+ & 65" Roku TV — TABLO DVR (8) Tab: The 3rd top-level image tab alongside MOVIES (107) and TV SHOWS (48 SERIES), filtering OTA recordings across All Recordings, NFL & MLB Sports, Series & Episodes, Local News, 47.1 WMSNFOX, and 15.1 WMTVNBC.

What We Built & Why

  • Zero-Cloud HMAC-MD5 Tablo 4th Gen Client (packages/robos-lib/tablo-client.js): Tablo 4th Gen DVRs (model TF1282B-01, firmware 2.2.54) expose an HTTP API on port 8887 that rejects unsigned requests. tablo-client.js implements the canonical 4-line HMAC-MD5 request signature (METHOD\nPATH\nMD5(BODY)\nDATE), discovers Tablo units on the LAN, batch-fetches all recording categories (/recordings/sports/events, /recordings/series/episodes, /recordings/movies/airings) and OTA guide channels (/guide/channels), and requests fresh playback tokens via POST /recordings/.../watch.
  • Broadcast Recording Thumbnail Acquisition + Live Frame Capture for Active Recordings: Completed recordings expose a 16:9 broadcast snapshot (video_details.snapshot_image.image_id) on the Tablo, which RobOS downloads and caches in ~/.cache/robos/tablo-images/ and bundles as pkg:/images/tablo-<id>.jpg inside the Roku SceneGraph channel. For in-progress recordings (state: "recording", where Tablo sets snapshot_image: null until the broadcast ends), fetchTabloImage() automatically opens the recording's live HLS stream and captures a 640×360 JPEG frame via ffmpeg -frames:v 1 so active sports and news recordings immediately display a real broadcast thumbnail on both desktop and the 65" Roku TV.
  • Desktop H.264/AAC Live Transcoding & Electron CSP Fix (packages/robos-lib/tv-engine.js, packages/robos-tv/renderer/index.html): Over-the-air ATSC broadcasts use MPEG-2 video and Dolby AC-3 audio, which Chromium's HTML5 <video> element cannot decode natively. The portal server's GET /api/tablo/stream endpoint spawns an ultra-low-latency ffmpeg pipeline (-c:v libx264 -preset ultrafast -tune zerolatency -c:a aac -f mp4 -movflags frag_keyframe+empty_moov+default_base_moof) with seek offset support (?startSec=), and we fixed the renderer's Content-Security-Policy (replacing the invalid http://192.168.* wildcard with standard http: https: scheme sources) so local playback starts immediately.
  • 65" Roku OS SceneGraph TABLO DVR Tab & Native 60fps HLS Rewriter (/api/tablo/roku.m3u8): We expanded Row 1 of the Roku SceneGraph channel (MainScene.xml / MainScene.brs) and the :19210/movie-player portal to 3 top-level image tabs (MOVIES, TV SHOWS, TABLO DVR), added a dedicated 16:9 broadcast thumbnail frame in the Hero Spotlight banner, and built GET /api/tablo/roku.m3u8 to dynamically fetch a fresh Tablo watch lease and rewrite relative /stream/seg.ts and /stream/pl_iframe.m3u8 URIs to absolute LAN URLs on 192.168.1.55:80—allowing the Roku TV's hardware decoder to play 60fps OTA broadcasts directly with zero transcoding.
# Verify the 22-test Smart TV Studio, Tablo DVR & Roku SceneGraph test suite
node --test packages/robos-test/tests/robos-tv/unit.test.js

# Query the live Tablo 4th Gen DVR catalog and stream endpoints on :19210
curl -s http://127.0.0.1:19210/api/tablo | jq '{name: .device.name, ip: .device.ip, recordingsCount: .recordingsCount}'
curl -sI "http://127.0.0.1:19210/api/tablo/image/205443.jpg?ip=192.168.1.55&port=8887"
curl -s "http://127.0.0.1:19210/api/tablo/roku.m3u8?path=/recordings/sports/events/205443&ip=192.168.1.55&port=8887"