Server-less OTT-Only Playout

We asked ourselves the question: If we would startup a TV channel for distribution only over the Internet (OTT) today, how would a technical solution for this look like? The answer to this question was elaborated around in a previous post here, and now we have at our website tv.eyevinn.technology a proof-of-concept demonstration of a fully “server-less” OTT-only TV channel playout. In this post we will describe how this was done.

The reason why we wanted a server-less solution was that we wanted the cost to be driven directly by the amount of content we have and number of active users. Basically if no-one were watching we would only pay for the storage cost. A storage cost that correlated directly to the amount of content available. Another benefit of having a server-less design is that it allows us to scale up and down the solution to handle peak hours and off-hours.

A TV channel is an editorial based packaging of content designed for the laid-back viewer. Though the on-demand watching is becoming a big portion of TV consumption today there are still room for a service directed to a viewer that doesn’t know exactly what to watch, which is why we believe consumption of TV channels still has a place in this landscape. But instead of having a number of fixed and pre-programmed TV channels each viewer will have their own personalized TV channel. However, that doesn’t mean that we would have one encoder per viewer and instead we found a more efficient and scalable way of achieving this.

The general concept that we used is that we take a content repository with already encoded video on demand (VOD) packages and dynamically “stitch” these VOD packages together into a “live” stream. For the player and viewer it looks and feels like a “live” TV channel but it is actually created on-the-fly by concatenating the already prepared VOD packages.

System Architecture for a Server-less OTT-only Playout

Channel Engine

The component that dynamically stitch these VOD packages together is what we call the Channel Engine. It is a NodeJS application deployed on Heroku. Heroku is an app-engine platform that allows you to easy scale up and down to meet performance requirements.

To understand what the Channel Engine does, let's start with a short explanation on Apple HLS and streaming format in general. The key difference between a broadcast stream and an OTT stream is when a broadcast stream pushes video to the player an OTT stream is instead pulled by the video player. Very similar to how an image or HTML document is pulled from a web server to the browser. In OTT streaming we have a set of video files transcoded in various resolution and sizes, and to be able to switch between the different resolutions during playback the video files are split into smaller chunks (3-9 seconds long). The location and order of these chunks are described by a manifest file (suffixed by .m3u8 in Apple HLS).

For VOD content all these chunks are available from the start and for Live content these chunks are continuously made available. As these new chunks are appended to the HLS manifest and older chunks removed, an HLS video player is instructed to continuously refresh and refetch this manifest from the server.

Based on this we can emulate an HLS live stream simply by picking the video chunks from the VOD content and having an engine (Channel Engine) constructing and updating the "live manifests" that the video player is fetching. In order to do this we first need to "slice" the VOD content chunks into media sequences. Each media sequence corresponds to a subset of the VOD content to simulate that new video chunks are appended.

The pseudo code for the Channel Engine can be described like this (simplified):

server.get('/live/master.m3u8', function(req, res) {
session = generateNewSession();
res.send(
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=300000,RESOLUTION=...
master300000.m3u8;session=$session
#EXT-X-STREAM-INF:BANDWIDTH=600000,RESOLUTION=...
master600000.m3u8;session=$session
...
);
});

server.get('/live/master(\d+).m3u8;session=(.*)', function(req, res) {
bandwidth = $1;
session = $2;
vod = getCurrentVod(session);
mediaSequence = getNextMediaSequence(vod, session);
res.send(mediaSequence.m3u8);
});

Content Distribution

While the Channel Engine is responsible for providing the video players with the HLS manifests they need, the actual video segments from the VOD package is distributed over a CDN. In this solution we have placed the VOD packages in an AWS S3 bucket connected to an AWS CloudFront CDN. With this model we don’t need a web server running 24x7 as that is handled by AWS and we have a cost-model that is based on the amount of content stored in the bucket and the amount of data transferred out from the bucket over the CDN. When no-one is requesting any video segments we only pay for the cost of storage.

Frontend Distribution

In a similar fashion the frontend and user-interface (the tv.eyevinn.technology website) is distributed from an S3 bucket and CloudFront CDN. As the website doesn’t need any backend logic and only need to serve static HTML, images and Javascript files there is no need for a web server.

Content Ingest

To get content into the system, transcoded and packaged to VOD HLS packages we use an Elastic Transcoder pipeline. A Elastic Transcoder job is created by a Lambda function that triggers on an S3 bucket create object event.

Lambda function to trigger transcoding job

The transcoder puts the result in the S3 bucket that is used for the Content Distribution as earlier described. The content and URI is then registered in a Dynamo DB.

Asset Manager API

The Channel Engine is only responsible for stitching VOD assets together and to know what VOD assets to stitch together it requests a VOD via the Asset Manager API. The Asset Manager API is a Lambda function exposed through an API gateway and at the time of writing it provides an endpoint that randomly picks a VOD from the Dynamo DB. This is the area where we have a lot of potential to customize and personalize the TV channel. More on this in a later post.

Demo

To directly play “your” live HLS stream you can just put the following link in your HLS player (click on it on Apple devices): https://ott-channel-engine.herokuapp.com/live/master.m3u8 or go to our website: https://tv.eyevinn.technology/ (works best on a desktop PC or Mac).

Me and my colleagues would like to thank you for reading and if you want to know more about this proof-of-concept you can contact me, Jonas Rydholm Birmé, on Twitter or email.

  • Twitter: @JonasBirme
  • Email: jonas.birme@eyevinn.se

Eyevinn Technology is the leading independent consultant firm specializing in video technology and media distribution, and proud organizer of the yearly nordic conference Streaming Tech Sweden.

Like what you read? Give Eyevinn Technology a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.