I've been building OTNet for the better part of two years, and I wanted to write about it properly. Not a pitch. Not a feature list. Just the honest story of what it is and how the pieces fit together.
OTNet started as an answer to a problem I kept hitting whenever I talked to small studios, independent broadcasters, podcast networks, and creators who wanted to run their own streaming operation. The big platforms wanted them inside a walled garden. The white label vendors wanted a six figure deal before they'd take a meeting. Everyone in between was stitching five or six tools together, paying for each, and still ending up with something held together by tape.
So I sat down and asked the question properly. What would a single platform look like if you actually owned it end to end? From the moment a producer drops a raw file onto a desktop, through encoding, DRM, ingest, scheduling, playout, all the way to a viewer pressing play on a phone or a television. No middlemen. No surprise bills. That's the shape of OTNet today.
The shape of the platform
OTNet ships in four parts. A desktop application (Electron) for producers: encoding, DRM key generation, CMAF packaging through Shaka Packager, uploads to cloud storage, registration with the platform. A website (Next.js App Router, Mongo, Firebase auth) as the control plane. Television apps on Tizen, webOS, Fire TV, and Android, built on Lightning so a single canvas based codebase ships to every screen. And a player, the OTNet player, that runs everywhere the viewer goes: browser, desktop preview, television app, third party iframe.
Each piece is its own codebase on purpose. A producer encoding a 50 GB master has nothing in common with a viewer pressing play from a hotel room. Splitting cleanly lets the right tool do the job.
API engineering
The website's API is where the project earns its keep day to day. There's a dashboard API for authenticated users, a public API layer that mirrors the dashboard, and a third partner surface that accepts API keys with proper rotate flows (instead of misleading copy buttons). Every resource (content, categories, people, organizations, channels, programs, media, genres) has a CRUD page on the dashboard and an endpoint behind it, and the two stay in lockstep because they share the same handlers.
Each dashboard page ships with a sliding API panel. A developer can hit the same endpoint from inside the UI, see the request and response, copy the call into their own code. That removed an entire class of "where's the docs?" support tickets.
AI-readable by design
The documentation surface for each resource is generated from the same schema that drives the API and the dashboard. It's also exposed as a clean, machine readable surface that an AI assistant can read directly. The practical upshot: a publisher can ask Claude or ChatGPT "how do I create a new program from a piece of content using OTNet" and get working code back, because the model is reading the live shape of the API rather than guessing from training data.
That wasn't an afterthought. Once you accept that a meaningful share of integration work will be done in tandem with an AI assistant, you start designing the API for two readers: humans first, then the model that's helping them.
The session DRM proxy
The piece I'm most proud of on the API side is the session DRM proxy. When a viewer presses play, the player asks the website for a short lived JWT proving they're allowed to watch that specific piece of content. The player then routes its license requests through the website rather than hitting BuyDRM or EZDRM directly. The website unwraps the publisher's secrets from the database (AES 256 GCM, stored per organization), forwards the request to the correct provider with the correct authorization header, and pipes the response back.
The viewer never sees the publisher's credentials. The publisher never has to expose them. And switching providers becomes a settings change, not a code change.
The player
The player is one set of source files compiled into four web components: video, audio, circular (podcast and short form), and square (social and portfolio). Same engine. Same DRM helper. Same controls. Same settings menu. Same picture in picture. The skins are the only thing that differs.
Under the hood the engine wraps Shaka Player for adaptive streaming, picks DASH or HLS per platform, falls back to native HLS on Safari for FairPlay, and exposes a uniform setup API. Configuration is a single JSON object. Drop the same config into any skin and it just works. That uniformity is what lets one player serve every surface, with a fix in one place rolling out everywhere.
Where it's going
A WordPress plugin so publishers can drop OTNet players into existing posts without writing any code. Per viewer and per device token binding for studios that want premium tier protection. Live channel scheduling against the existing program model so an organization can run a 24 hour linear feed alongside their on demand catalogue. Better analytics, better discovery, better recommendations.
But the bones are solid. A producer can record, encode, protect, ingest, schedule, distribute, embed, and measure, all from inside a single platform they actually own. That was the whole point.