FFMPEG Encryption

20,126

Yes, you can do it with ffmpeg. You need to write the key from the database to a file, let's say video.key.

You need a second file, let's name it key_info which is the key info file. It has the following format:

key URI
key file path
IV (optional)

Eg:

http://example.com/video.key
video.key

You tell ffmpeg to use it to encrypt your segments with the hls_key_info argument:

ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -hls_time 10 -hls_key_info_file key_info playlist.m3u8

This will encrypt your segments with AES-128 in CBC mode and add the relevant tags to your playlist:

#EXT-X-KEY:METHOD=AES-128,URI="http://example.com/video.key"

You can also manually encrypt the segments if you want with openssl. Here's an example script, where each IV is equal to the segment index:

#!/bin/bash
ts_dir=/path/to/ts/

key_file=video.key
openssl rand 16 > $key_file
enc_key=$(hexdump -v -e '16/1 "%02x"' $key_file)

pushd $ts_dir

ts_cnt=$(ls *.ts | wc -l)
((ts_cnt--))

i=0
for i in $(seq -f "%01g" 0 $ts_cnt); do
    iv=$(printf '%032x' $i)
    ts_file=segment-$i.ts

    echo [$i] $ts_file

    openssl aes-128-cbc -e -in $ts_file -out encrypted_${ts_file} -nosalt -iv $iv -K $enc_key
done

popd
Share:
20,126
rickyma924
Author by

rickyma924

Updated on July 21, 2022

Comments

  • rickyma924
    rickyma924 almost 2 years

    I am doing a project with encrypting video and I have a few questions for the procedure.

    I used a command to transcode mp4 to HLS with a ts segment duration of ~10 seconds.

    First, I need to encrypt those videos with a key from database. However, I have no idea for the encryption whether working with ffmpeg or not.

    Second, if the encryption can work without ffmpeg, so what should I do? I have searched in google which includes something like openssl / aes but there is no a detailed step for me to follow, even the ffmpeg link: http://www.ffmpeg.org/ffmpeg-all.html#srtp

    Could anyone give me a hand, teaching me how to encrypt a video? Thanks to you.

  • rickyma924
    rickyma924 over 8 years
    After running the command, the following error appears: Unrecognized option 'hls_key_info_file'. Error splitting the argument list: Option not found
  • aergistal
    aergistal over 8 years
    @rickyma924 you may be using an outdated version of ffmpeg. Build it from source or grab a package/static build. Here's a link to the hls documentation: ffmpeg.org/ffmpeg-formats.html#Options-2
  • aergistal
    aergistal over 8 years
    @rickyma924 post the full command please, I will try it. If you installed a new ffmpeg make sure you're using the right one which ffmpeg.
  • rickyma924
    rickyma924 over 8 years
    ffmpeg -i bunny.mp4 -c copy -bsf:v h264_mp4toannexb -hls_time 10 -hls_key_info_file file.keyinfo playlist.m3u8
  • aergistal
    aergistal over 8 years
    Works for me. Do a ffmpeg -version and post the result.
  • rickyma924
    rickyma924 over 8 years
    ffmpeg version git-2015-02-13-849ad51 Copyright (c) 2000-2015 the FFmpeg developers built with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-11) Maybe the one I downloaded is a static version and cannot replace my original one
  • aergistal
    aergistal over 8 years
    @rickyma924 check the binary path with which to make sure you're using the correct one.
  • rickyma924
    rickyma924 over 8 years
    when I use -which, it shows me ffmpeg stored in ~/bin
  • aergistal
    aergistal over 8 years
    Did you use the git version or the release. Try the git.
  • rickyma924
    rickyma924 over 8 years
    how to make the static ffmpeg to be the default one? is it just do export static/ffmpeg/path:$PATH?
  • aergistal
    aergistal over 8 years
    I don't know where you installed it but run it from its directory, eg: ./ffmpeg -i ...
  • aergistal
    aergistal over 8 years
  • chovy
    chovy over 8 years
    Is it possible to use this technique to decrypt a live stream?
  • aergistal
    aergistal over 8 years
    @chovy This is encryption not decryption. But yes you can both encrypt or decrypt a live AES-128 HLS stream.
  • chovy
    chovy over 8 years
    what options do i pass to ffmpeg to decrypt it?
  • aergistal
    aergistal over 8 years
    @chovy None, you just point it to the m3u8 and it will use the EXT-X-KEY information in it automatically.
  • chovy
    chovy over 8 years
    I was hoping to override the key in the playlist.m3u8 -- as I don't have control over that.
  • StormyKnight
    StormyKnight about 7 years
    Newby question. Where do I get a key?
  • aergistal
    aergistal about 7 years
    @StormyKnight you generate one: openssl rand 16 > $key_file. It can be anything as long as it's 16 bytes long.
  • Adam Soffer
    Adam Soffer almost 6 years
    Is it possible to achieve some sort DRM solution using this encryption method? Using ffmpeg, I'd like to be able to encrypt a stream with a user's public key so that it can only be decrypted with that user's private key but I'm not sure if this is possible.
  • Whome
    Whome over 4 years
    @aergistal Thank you, very helpful example. Do I understand hls manifest KEY-URL is just a php/servlet/static file url to the raw encryption key file response. It does not do any dash-widevine/playready level PKI key exchange server things? So it's easy to have a own customized hls key delivery url entrypoint?
  • aergistal
    aergistal over 4 years
    @Whome Yes it's just the raw key, not DRM.