Cloudflare TV: Building a 24/7 live channel on the edge
Cloudflare TV was conceived with a simple premise: make live, 24x7 programming that is as engaging as the tech television of the 90s, but with modern convenience. The engineering team behind it set several foundational goals from the start:
- Guest participation should be as effortless as joining a standard video call.
- The channel must have continuous programming around the clock.
- The entire broadcast infrastructure must run in the cloud, requiring no on-premise hardware or manual intervention.
Reaching these goals meant choosing a path that wasn't entirely straightforward. While off-the-shelf video platforms were evaluated, they often fell short of our strict requirements. Most infrastructure is designed for event-based or on-demand viewing, not for a persistent, linear broadcast. Creating a seamless experience for presenters that didn't force them to install new software was also a hurdle. This led the team to consider using familiar tools combined with edge infrastructure.
The Zoom-to-RTMP pipeline
The breakthrough came from a feature inherent to a tool our team and guests already used daily: Zoom. Since Zoom can push a live video stream to any RTMP endpoint, we had a potential path to create an extremely low-friction broadcasting setup for presenters.
RTMP (Real-Time Messaging Protocol) is a long-standing standard for pushing high-volume video data over TCP. Although originally built for Macromedia Flash, it remains the backbone for many live streaming platforms, including YouTube, making it a reliable and widely supported protocol. By configuring Zoom with a specific RTMP target URL, we could redirect a meeting's video feed to our own servers.
To receive this feed, we established an NGINX server equipped with the RTMP module. An important distinction is that a browser cannot directly play an RTMP stream, so the server's role had to go beyond simple ingestion.
In our nginx.conf, we defined a virtual application called live. Within this application block, directives were added to ingest the incoming RTMP feed and package it into HLS segments. This conversion step is crucial because it allows for standard web browsers to play the stream without any plugins. Once NGINX was configured to handle both ingestion and adaptive streaming output, we had a working prototype that could broadcast a Zoom call across the Cloudflare network.
Orchestrating a continuous schedule
Solving the live-stream aspect covered the primary "guest experience" requirement, but a single, endless call doesn't constitute a broadcast channel. To create a true 24/7 schedule, we needed to handle program scheduling and allow for seamless transitions between distinct events without breaking the user's video stream.
Our architecture to solve this required a few new components:
- A scheduling system to define which content plays at which time, potentially days in advance.
- A system of "virtual rooms" that could pull from different sources, such as live calls or pre-recorded files from Cloudflare Stream.
Once these were in place, a dynamic scheduler could switch the on-air feed to whatever content was scheduled next, ensuring no buffering or refreshes were needed for the viewer.
Managing content creation with Contentful
For the schedule, we integrated Contentful, a headless CMS with an API-first design. This removed the need for us to maintain a complex database to handle the programming calendar. The CMS stores essential metadata for each show—its title, the presenters, airtime, and each entry is synchronized to the public-facing schedule on our site.
We utilized Workers to query Contentful for this data. A more complicated task was linking these scheduled segments to Zoom calls. Creating each call manually would have been tedious. Instead, we automated it: when a Contentful event is published, it triggers a webhook to a Cloudflare Worker endpoint. The Worker then interacts with the Zoom API to create a new meeting, auto-configure its RTMP settings to push to our NGINX server, and generate a custom calendar invite for the producer to send to the guest.
Virtually routing content with Brave
To manage the actual video feeds, we turned to the BBC's open-source project, Brave. This software allowed us to create our "virtual rooms," each continuously pulling a video signal from its designated source (be it a live Zoom meeting from NGINX or a file from Cloudflare Stream).
Brave's orchestration engine essentially handles two continuous operations: ingesting these multiple video sources into their respective virtual rooms, and taking whichever room is marked as "on-air" and pushing that combined feed back to NGINX around the clock. This gave us the flexibility to smoothly cut between a live segment ending at 11:00 AM and a pre-recorded show due to start immediately after, ensuring a constant output.
Streamlining the connection
Across this infrastructure, Cloudflare Workers acted as the central "glue" that connected all components. The public-facing video player itself is hosted on Worker Sites, allowing the frontend to fetch scheduling data from the same edge network. Workers removed the need to stand up a dedicated backend gateway, letting us move quickly from brainstorming to a broadcast-ready system with just a few server configurations and API integrations.
Now that the initial infrastructure is live, our roadmap includes refining the experience for both viewers and participants. Upcoming priorities include adding closed captioning, exploring ways for viewers to call in and interact during shows, and adapting the experience for connected TV platforms like Apple TV and Roku.



