In this article, I present an architecture that I use for building my video streaming website with open source components. I am new to the video streaming technology, but I was positively surprised at the number of tools available to make a video streaming service.

Technical requirements of the service

  • Should have authorization for retrieving the videos.
  • Should include a commerce and payment (iDEAL) platform.
  • Should be performant (also in uploading and processing videos).
  • A non-technical user should be able to upload a video.

High-level overview

High-level architecture

DASH

In any modern video streaming service, you want to use a video streaming technology which takes into account the bandwidth of the user. When a user is on a slow internet connection you want to display a lower quality of the video than when he is on a fast connection. The industry standard for video streaming over HTTP is MPEG-DASH. It works with a DASH manifest in where you specify the different video and audio files you have for the video. I mainly used this tutorial from Google by Paul Lewis to get me started.

Symfony

The Symfony API application is the gateway to the video processing pipeline, and that is the only function of the API. I have chosen the component-based architecture to be able to attach multiple video services platforms to the processing API and to have a clear split of concerns. The input is a raw video file (e.g., .mp4) and the output is a collection of DASH files stored on an AWS S3 bucket.

Dash files on S3

To make the API feel performant I handle all the video processing asynchronous with a combination of RabbitMQ and the Messenger Component of Symfony.

NGINX Proxy

For watching the videos an important component is the NGINX proxy. This is the gatekeeper to the user and the video. NGINX is able to perform authorization before giving access to the video files. The solution consist of using the auth_request module in combination with the third party ngx_aws_auth module.

The basic trick is to redirect the NGINX auth_request to your web framework (in my case Drupal 8), check access of the filename, and return a Symfony response.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  public function checkAccess($filename) {
    // It has a full Drupal Bootstrap so you can go wild here and get the current user.
    $hasAccess = $this->accessCheckerService->checkAccessFilename($filename);

    if ($hasAccess) {
      $response = new Response(
        'Content', Response::HTTP_OK, ['content-type' => 'text/html']
      );
    }
    else {
      $response = new Response(
        'Content', Response::HTTP_FORBIDDEN, ['content-type' => 'text/html']
      );
    }
    return $response;
  }

When the response is OK, it can go ahead and serve the video files either from AWS S3 or the NGINX proxy cache.

Shaka player

There are two strong open source video players to choose from: Shaka Player and dash.js. Both are very capable and fit the requirements but I have chosen the Shaka Player, mainly because there was more development activity in the repository. There is a detailed summary of the difference between the two in this issue.

In Drupal 8 it is easy to load the Shaka Player by making a custom video field formatter and attach the javascript library:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// viewElements in FieldFormatter .
...
 '#attached' => [
            'library' => ['video_watch/shaka-player'],
            'drupalSettings' => [
              'video_watch' => [
                'video' => $this->viewValue($item), // Video DASH manifest. Goes to the NGINX Proxy.
              ],
            ],
          ],

          '#markup' => '<video id="video" width="1280" height="720" controls autoplay></video>',
          '#allowed_tags' => ['video'],
...
1
2
3
4
5
6
7
8
# video_watch.libraries.yml
shaka-player
:
  version
: 1.x
  js
:
    js/shaka-player.compiled.js
: {}
    js/play-video.js
: {}
  dependencies
:
   - core/drupalSettings

Drupal 8

Drupal 8 was chosen as the main platform mainly because it provides much functionality out of the box and I have experience with it. The Drupal Commerce module forms the main base for ordering a product and conducting a payment. As the first project will be a Dutch service we support payments with iDEAL with Mollie and the Commerce Mollie module.

Discussion

My proof of concept is complete, and it works quite well. The next step is to build the streaming service and to test the architecture when scaled to hopefully many users.

It is very doable to make your video streaming solution but be prepared to utilize many components and tools. As a reference, it took me around 3 weeks of work to get the proof of concept up and running.


Leave a Reply

Your email address will not be published.