HTML5 DRM Media Stream

This document explains how you can encrypt and stream HTML5 video. As a demo, this uses the ClearKey system, but it works pretty much the same on other key systems.

Light knowledge of the command line of your system is required.

Requirements

Note: This guide is for Windows operating systems but all tools work on all major systems

  1. A functioning python3 installation
  2. MP4 toolkit from Bento4
  3. A video file
  4. (Optional) Ffmpeg

Ffmpeg is only needed if the video is not already in a proper streamable MP4 format.

Convertig the video

If your video is not already in a web browser compatible format, you need to convert it.

Command: C:\Path\To\ffmpeg.exe -i "INFILE" -strict experimental -acodec aac -ac 2 -ab 128k -vcodec libx264 -f mp4 -crf 24 -movflags +faststart -y "output.mp4"

Explanation of arguments

Batch conversion

Tip: If you plan on doing this multiple times, create a batch file with this content:

@ECHO OFF
:CONV
IF "%~1"=="" GOTO END
C:\Path\To\ffmpeg.exe -i "%~1" -strict experimental -acodec aac -ac 2 -ab 128k -vcodec libx264 -f mp4 -crf 24 -movflags +faststart "%~dpn1.mp4"
SHIFT
GOTO CONV
:END

This now allows you to drag and drop individual video files on it to convert the file without having to type the command every time. You can drop multiple files on it at once to convert them all.

Encrypting and splitting

to properly play the file it must be fragmented, split, and encrypted.

The MP4 toolkit contains a file named mp4dash.bat in the "bin" directory. This is how it's used:

SETLOCAL
SET MP4=%~dpn1.temp.mp4
C:\Path\To\mp4fragment.exe "%~1" "%MP4%"
CALL C:\Path\To\mp4dash.bat -o C:\Path\To\output --eme-signaling=pssh-v1 --clearkey --clearkey-license-uri=API_URL --encryption-key=KEY "%MP4%"
DEL "%MP4%"

Save this code into a batch file and it will convert and encrypt the mp4 file you drag onto it. The Output directory (C:\Path\To\output) must not exist or it will abort. The script creates the output directory for you.

"KEY" should be replaced with your encryption key. Ideally it's a different key for every video. It consists of two 32 character hexadecimal values concatenated by :. The first value is the key id and the second value the key itself. Do not lose the key or you will have to encrypt your base file again using a new key.

You can generate a key right here in your browser if you want to:

"API_URL" should be replaced with the URL to your own licensing script (for contents see below). This is optional and you can remove the entire argument if you rather hardcode the key into the website.

When done sucessfully, the output path will be created, and it will contain an "mpd" file as well as subdirectories with files.

Deploying

After conversion you want to upload the entire video output folder to your web server. You want to create a few additional files:

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Encrypted Media Player</title>
        <script src="https://cdn.dashjs.org/latest/dash.all.min.js" defer></script>
        <script src="video.js" defer></script>
    </head>
    <body>
        <h1>Encrypted media player</h1>
        <video controls></video>
    </body>
</html>

video.js

Change "video/stream.mpd" to match the file path on your server

function init() {
    var v = document.querySelector("video");
    var player = dashjs.MediaPlayer().create();
    player.initialize(v, "video/stream.mpd", false);
}

init();

License script

The license script is only needed if you don't hardcode the key. The dash player will make a POST request to it with the key id. It should respond with a JSON object that contains the requested key.

The request body will be a raw JSON object with a list of key ids in this format:

{
    "kids": ["..."],
    "type": "temporary"
}

In your case, only one key id will be sent. If you were to encrypt video and audio differently, two ids would be present.

The response should be a raw JSON and look like this:

{
    "keys": [{
            "kty": "oct",
            "k": "...",
            "kid": "..."
        }
    ],
    "type": "temporary"
}

The number of keys in the "keys" enumeration should match the requested number of keys, but doesn't necessarily has to be in the same order.

Key and id format

Keys and ids in license requests/responses are formatted specially. The key and id are submitted as base64 encoded value instead of a hex string.

The base64 encoded value is altered as follows:

Hardcoded keys

If you want to use hardcoded keys instead, you want to extend the JavaScript file with the code below just before the "player.initialize" line:

var protData = {
    "org.w3.clearkey": {
        "clearkeys": {
            "kid": "key"
        }
    }
};
player.setProtectionData(protData);

Replace "kid" and "key" in the dictionary with the encoded key id and key. How to encode the values is given in the chapter Key and id format.

Copyright © 2022 by Kevin Gut 📧 | More services | Generated for 3.141.30.221