Converting MP4 to Encrypted HLS Video with OpenSSL and FFmpeg

HLS, which is a video streaming technology developed by Apple Inc., is not a video file in of itself. Rather, HLS consists of a single m3u8 file that lists video file chunks. My tutorial on using HLS for video on demand provides a more detailed explanation on how this technology works and how it can be used for digital rights management (DRM). I suggest you give it a read.

In that tutorial, I mentioned that the m3u8 file is a playlist. What I didn’t mention is that it’s possible to download this file and open it with a plain text editor. Doing so will reveal the location of the .ts video file chunks, which are usually found in the same path as the m3u8 playlist. A would-be pirate can use the information found in the m3u8 file to download each .ts file chunk; however that can be become tedious process assuming there are hundred of chunks. I have already thought of a ways to automate the download process and subsequently play the video in its entirety with VLC, but there are extra steps content creators and webmasters can take to deter unauthorized video downloads.

You will need terminal access to a machine with OpenSSL and FFmpeg already installed. You’ll also need a streaming server.

The first thing we need to do is generate a key file:

openssl rand 16 > keep_this_file_safe.key

You can name this file whatever you want, but I would keep the .key extension.

Now we need to create a .keyinfo file. FFmpeg will use this text file to convert the MP4 to encrypted HLS:

echo http://192.168.0.101/keys/keep_this_file_safe.key > my.keyinfo

This will create a new file called my.keyinfo with first line specifying the URL of your key file on the web server. You will have to upload the key file to that location so the encrypted video is playable. Change the URL according to your setup.

echo /path/to/keep_this_file_safe.key >> my.keyinfo

Running this command will add a second line to my.keyinfo that specifies where the key file is actually located in your Linux box. This is what FFmpeg will actually look for when encrypting the .ts file chunks.

Next, we’ll need a call back to the key file:

echo $(openssl rand -hex 16) >> my.keyinfo

Your .keyinfo file should look something like this:

http://192.168.0.101/keys/keep_this_file_safe.key
keep_this_file_safe.key
0123456789ABCDEF9876543210ABCDEF

Now it’s time to generate the encrypted HLS files with FFmpeg. Adjust the length of your .ts files and the video resolution accordingly before running this command:

ffmpeg -i my_video.mp4 -profile:v baseline -level 3.0 -s 1280x720 -start_number 0 -hls_time 10 -hls_list_size 0 -hls_key_info_file my.keyinfo -f hls my_video.m3u8

The time it takes to generate your HLS content will depend on the processing power of your machine. Upon completion, you will have HLS video content that cannot be played unless the key file is in the location specified in the first line of the keyinfo file.

Upload your .key file and encrypted HLS video content to a streaming server and you’re good to go.

Make sure you implement some form of security for the .key file so it is only accessible when needed for video playback. This can be accomplished with .htaccess, but that’s beyond the scope of this tutorial.