Widewine with ReactJS

The following guide helps you set up DRM with Shaka Player React

Shaka Player React is very popular player to play videos on react web applications. It can play both HLS and DASH streams and supports DRM.

To keep the scope of this document limited we expect you have already setup React JS development environment and have an application running.

Step 1: Install the shaka-player-react package

npm i shaka-player-react

Step 2: Add the shaka component to your code

For the simplicity of this document we are making the changes in App.js itself and our web application would only have a video player in it.

...

function App() {
  return <ShakaPlayer autoplay src="https://video.gumlet.io/5f462c1561cf8a766464ffc4/61dd877c6ec832ab2aaa1837/7.mpd" />;
}

...

If you run the application and navigate to http://localhost:3000/ you would see a video playing. This video was just an example and it is not an encrypted video. We will move to a DRM encrypted video next.

Step 3: Request for a license URL to play a video encrypted by DRM

DRM playback also needs Licence Server URL along with playback URL to play the content. The licence server URL will inform player the place from where the licence can be acquired.

For security reasons, Licence Server URL needs authentication token to be passed so it knows the request for licence is legitimate, due to this reason the code for generating a Licence Server URL should be on the server and not reside in the web application code.

Refer to this guide to generate the licence server URL on a backend server with your choice of programming language.

🚧

Remember!

Never generate the one time token for widevine licence server on client side. You must generate token from your server and send it to client.

Let us assume that your server root URL is https://example.com and sending a GET request on https://example.com/licence-url returns a licence server URL. We will call the fetch method in the components useEffect hook and set it to a state variable to be used to initialise the video player with the Licence Server URL.

...

function App() {
  const controllerRef = useRef(null);
  const [signedLicenseURL, setSignedLicenseURL] = useState('');
    
  const getSignedLicenseURL = async () => {
     try {
      const response = await fetch('https://example.com/licence-url');
      const json = await response.json();
      setSignedLicenseURL(json.licence); // change according to your API response object
    } catch (error) {
      console.error(error);
    }
  }
    
  
  async function loadAsset() {
    const {
      /** @type {shaka.Player} */ player,
      /** @type {shaka.ui.Overlay} */ ui,
      /** @type {HTMLVideoElement} */ videoElement
    } = controllerRef.current;

    player.configure({
      drm: {
        servers: {
          'com.widevine.alpha': signedLicenseURL
        },
        advanced: {
          'com.widevine.alpha': {
            'videoRobustness': 'SW_SECURE_CRYPTO',
            'audioRobustness': 'SW_SECURE_CRYPTO'
          }
        }
      }
    });

    await player.load('<DRM ENCRYPTED VIDEO URL>');

    videoElement.play();
  }

  useEffect(() => {
    if(!signedLicenseURL){
        getSignedLicenseURL();
    }else{
        loadAsset();
    }
  }, [signedLicenseURL]);

  return <ShakaPlayer ref={controllerRef} />;
}

...

👍

Done

You can now play your DRM protected videos in a React Web Applications

Full Code Snippet

import './App.css';
import 'shaka-player/dist/controls.css';
import React, { useRef, useEffect, useState } from 'react';
import ShakaPlayer from 'shaka-player-react';

function App() {
  const controllerRef = useRef(null);
  const [signedLicenseURL, setSignedLicenseURL] = useState('');
    
  const getSignedLicenseURL = async () => {
     try {
      const response = await fetch('https://example.com/licence-url');
      const json = await response.json();
      setSignedLicenseURL(json.licence); // change according to your API response object
    } catch (error) {
      console.error(error);
    }
  }
    
  async function loadAsset() {
    const {
      /** @type {shaka.Player} */ player,
      /** @type {shaka.ui.Overlay} */ ui,
      /** @type {HTMLVideoElement} */ videoElement
    } = controllerRef.current;

    player.configure({
      drm: {
        servers: {
          'com.widevine.alpha': signedLicenseURL
        },
        advanced: {
          'com.widevine.alpha': {
            'videoRobustness': 'SW_SECURE_CRYPTO',
            'audioRobustness': 'SW_SECURE_CRYPTO'
          }
        }
      }
    });

    await player.load('<DRM ENCRYPTED VIDEO URL>');

    videoElement.play();
  }

  useEffect(() => {
    if(!signedLicenseURL){
        getSignedLicenseURL();
    }else{
        loadAsset();
    }
  }, [signedLicenseURL]);

  return <ShakaPlayer ref={controllerRef} />;
}

export default App;

Did this page help you?