OTT

An over-the-top (OTT) media service is a streaming media service offered directly to viewers via the Internet. OTT bypasses cable, broadcast, and satellite television platforms, the companies that traditionally act as a controller or distributor of such content. OTT players which are most popular are  Netflix, Hulu, Disney+ and Amazon Prime Video etc. In this article we will try to create a simple video player in react. But before that we will discuss the challenges we have on the web.

Challenge

  • Different Browse support different protocols
  • No one standard currently supported ubiquitously.
  • Result in media being served in several different media formats to support all clients.

Protocols

  • Real-Time Protocols - (RTP, RTMP, RTSP etc)
  • HTTP streaming - (HLS, DASH etc.)

Adaptive bitrate streaming

Adaptive bitrate streaming is a technique used in streaming multimedia over computer networks. While in the past most video or audio streaming technologies utilized streaming protocols such as RTP () with RTSP, today's adaptive streaming technologies are almost exclusively based on HTTP.

DASH - enables high-quality streaming of media content over the Internet delivered from conventional HTTP web servers.

HLS - HLS resembles DASH in that it works by breaking the overall stream into a sequence of small HTTP-based file downloads, each download loading one short chunk of an overall potentially unbounded transport stream. It is developed by Apple.

How Dash Works?

  1. Download the Manifest file,  Dash uses a manifest file (mpd) which contains the various information about the audio component, video component, bit rates, and captions, etc.
  2. Parse Manifest file and validate.
  3. Determine the right bandwidth for the client
  4. Initialize for bandwidth
  5. Download the segment
  6. Pass segment to MSE
  7. Check bandwidth to determine if the change is necessary.

Implementation using dash.js:

dash. js is an initiative of the DASH Industry Forum to establish a production quality framework for building video and audio players that play back MPEG-DASH content using client-side JavaScript libraries leveraging the Media Source Extensions API set as defined by the W3C.

The first step to implementing the DASH.js video player framework is to import the library into your project, the latest of which can be found here.

As with our other players, you need to create your <video> tag and place it in your render function. This is what DASH.js will target to render your video.

Once again, we will give the video tag a reference of this.player so we can later use it to initialize DASH.js:

import React from "react";
import * as dashjs from "dash.js";
export default class VideoPlayer extends React.Component {
  state = {};
  render() {
    return (
          <video
            ref={player => (this.player = player)}
            autoPlay={true} 
          />
    );
  }
}

The final step to achieve playback is to instantiate your player on componentDidUpdate and provide it with your target URL:

export default class VideoPlayer extends React.Component {
  state = {};
  componentDidUpdate() {
      const url = "https://dash.akamaized.net/envivio/EnvivioDash3/manifest.mpd";
      const video = this.player;
      const dashjs = dashjs.MediaPlayer().create();
      dashjs.initialize(video, url, true);
  }
  render() {
    return (
          <video 
            ref={player => (this.player = player)}
            autoPlay={true} 
          />
    );
  }
}


Implementation using HLS.js:

Relying on HTML5 video and MediaSource Extensions to achieve playback, you can deliver reliable HLS playback in the browser quickly and efficiently.

Your first step to implementing HLS.js in React is to download the latest library and include it in your React project or install it from npm with npm i hls.js.

From there we create a standard <video> tag in our render function.

We will also give the player a reference of this.player so that we can use it later to instantiate our player framework:

import React from "react";
import Hls from "hls.js";
export default class VideoPlayer extends React.Component {
  state = {};
  render() {
    return (
          <video
            className="videoCanvas"
            ref={player => (this.player = player)}
            autoPlay={true}
          />
    );
  }
}

Once the video tag is in place, rendering a video in HLS.js is as simple as updating our componentDidUpdate to attach the media:

import React from "react";
import Hls from "hls.js";
export default class VideoPlayer extends React.Component {
  state = {};
  componentDidUpdate() {
      const video = this.player;
      const hls = new Hls();
      const url = "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8";
 
      hls.loadSource(url);
      hls.attachMedia(video);
      hls.on(Hls.Events.MANIFEST_PARSED, function() { video.play(); });
  }
  render() {
    return (
          <video
            className="videoCanvas"
            ref={player => (this.player = player)}
            autoPlay={true}
          />
    );
  }
}

Here you can see that our componentDidUpdate is loading the source stream, attaching it to the video player, and attaching a listener to manifest events in order to know when to play the video.



Implementation using video.js:

Video.js was built from the ground up in 2010 with the Javascript world in mind and is used on approximately 500,000 websites worldwide.

Its main selling point is that it aims to support all types of video format including adaptive video formats such as HLS and DASH.

implementing Video.js isn’t too much of a headache in React and can be up and running within minutes. To get started, you need to head here to download Video.js or import it using npm with npm i video.js.

From there, the Video.js player needs to be instantiated on componentDidMount before it is available for use:

import React from 'react';
import videojs from 'video.js'
export default class VideoPlayer extends React.Component {
  componentDidMount() {
    this.player = videojs(this.videoNode, this.props, function onPlayerReady() {
      console.log('Video.js Ready', this)
    });
  }
  componentWillUnmount() {
    if (this.player) {
      this.player.dispose()
    }
  }
  render() {
    return (
      <div> 
        <div data-vjs-player>
          <video ref={ node => this.videoNode = node } className="video-js"></video>
        </div>
      </div>
    )
  }
}

Conclusion

In this article, we have took a look at the basics of video playback and what happens behind the scenes once the consumer hits the play button. We have gone through three of the most popular ABS formats and the applications for each of them.