Creating playable DASH video encrypted with Clear Key encryption - encryption

I am attempting to transcode and DASH (with Clear Key encryption) a sample H.264 file for the Google Shaka player. Every set of steps I've been able to piece together online results in a playable version if unencrypted, then breaks down when I attempt to layer in encryption.
Unencrypted
Here are the steps I follow for the working unencrypted version:
Separate video from audio
ffmpeg -i input.mp4 -an -c copy video_only.mp4
ffmpeg -i input.mp4 -map 0:2 -c copy audio_only.m4a
Transcode the video into a working variant (only 1 for now)
ffmpeg -i video_only.mp4 -an -vcodec libx264 -s 1280x720 -c:v libx264 -b:v 384k -bf 2 -g 90 -sc_threshold 0 -an -strict experimental video_only_384kbps.mp4
3a. Create the mpd
MP4Box -dash 5000 -segment-name 'outputseg-%s' -url-template -bs-switching no \
-out output.mpd -rap \
audio_only.m4a \
video_only_384kbps.mp4
4a. Load the video into Osmo4 or Google Shaka
It plays.
With Encryption
Now, I attempt to layer in encryption. Starting from after step 2 above:
3b. Encrypt the variants with Clear Key
MP4Box -crypt drm.xml audio_only.m4a -out audio_only_encrypted.m4a
MP4Box -crypt drm.xml video_only_384kbps.mp4 -out video_only_384kbps_encrypted.mp4
where drm.xml contains a sample derived straight from the MP4Box/GPAC site:
<?xml version="1.0" encoding="UTF-8"?>
<GPACDRM type="CENC AES-CTR">
<!-- example for GPAC - keys are listed after the content and UL follows -->
<DRMInfo cypherIV="0x00000000000000000000000000000001" cypherKey="0x6770616363656E6364726D746F6F6C31" cypherOffset="9" type="pssh" version="1">
<BS ID128="6770616363656E6364726D746F6F6C31"/>
<BS bits="32" value="2"/>
<BS ID128="0x279926496a7f5d25da69f2b3b2799a7f"/>
<BS ID128="0x676cb88f302d10227992649885984045"/>
<BS bits="8" string="CID=Toto"/>
<BS ID128="0xccc0f2b3b279926496a7f5d25da692f6"/>
<BS ID128="0xccc0f2b3b279926496a7f5d25da692d6"/>
</DRMInfo>
<CrypTrack IV_size="16" IsEncrypted="1" first_IV="0x0a610676cb88f302d10ac8bc66e039ed" saiSavedBox="senc" trackID="1">
<key KID="0x279926496a7f5d25da69f2b3b2799a7f" value="0xccc0f2b3b279926496a7f5d25da692f6"/>
</CrypTrack>
</GPACDRM>
4b. Create the mpd
MP4Box -dash 5000 -segment-name 'outputseg-%s' -url-template -bs-switching no \
-out output.mpd -rap \
audio_only_encrypted.m4a \
video_only_384kbps_encrypted.mp4
5b. Load the video into Osmo4 or Google Shaka.
* On Osmo4, no errors are found but the player just hangs until I kill it
* On Google Shaka, I consistently receive a player error:
"CustomEvent {detail: Error: No DrmInfo exists!
at shaka.media.EmeManager.buildKeySystemQueries_ (http://localhost:808…, srcElement: null, target: s…a.p…r.Player, currentTarget: s…a.p…r.Player}
The output.mpd after 5b looks like this:
<?xml version="1.0"?>
<!-- MPD file Generated with GPAC version 0.5.2-DEV-rev566-g4c06d0f-master at 2015-09-03T19:17:57.544Z-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500S" type="static" mediaPresentationDuration="PT0H0M54.424S" maxSegmentDuration="PT0H0M4.992S" profiles="urn:mpeg:dash:profile:full:2011" xmlns:cenc="urn:mpeg:cenc:2013">
<ProgramInformation moreInformationURL="http://gpac.sourceforge.net">
<Title>output.mpd generated by GPAC</Title>
</ProgramInformation>
<Period duration="PT0H0M54.424S">
<AdaptationSet segmentAlignment="true" lang="eng">
<Representation id="1" mimeType="audio/mp4" codecs="mp4a.40.2" audioSamplingRate="48000" startWithSAP="1" bandwidth="140631">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc" cenc:default_KID="27992649-6a7f-5d25-da69-f2b3b2799a7f"/>
<SegmentTemplate timescale="48000" media="outputseg-audio_only_encrypted$Number$.m4s" startNumber="1" duration="239616" initialization="outputseg-audio_only_encryptedinit.mp4"/>
</Representation>
</AdaptationSet>
<AdaptationSet segmentAlignment="true" maxWidth="1280" maxHeight="720" maxFrameRate="24" par="16:9" lang="eng">
<Representation id="2" mimeType="video/mp4" codecs="avc1.64001f" width="1280" height="720" frameRate="24" sar="1:1" startWithSAP="1" bandwidth="375052">
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc" cenc:default_KID="27992649-6a7f-5d25-da69-f2b3b2799a7f"/>
<SegmentTemplate timescale="12288" media="outputseg-video_only_384kbps_encrypted$Number$.m4s" startNumber="1" duration="46080" initialization="outputseg-video_only_384kbps_encryptedinit.mp4"/>
</Representation>
</AdaptationSet>
</Period>
</MPD>
Software versions:
MP4Box: GPAC version 0.5.2-DEV-rev566-g4c06d0f-master
FFMPEG: ffmpeg version 2.6.3 Copyright (c) 2000-2015 the FFmpeg developers
built with Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Does anyone have any suggestions on how to proceed?

Related

How Can i Download this video? Encrypted m3u8?

Hello everyone For almost a whole month now I have been trying to download a file from a specific site
This is the link to the video
https://www.karaoke.co.il/api_play.php?type=clip&id=58370&autoplay=undefined&referer=karaoketv
The M3u8 files are split into 2 parts.
Video file
https://www.video-cdn.com/video/encrypt/750802ea0bc2d02fac93adeaa1398ec2/750802ea0bc2d...2-57d9518fae69
And an audio file
https://www.video-cdn.com/video/encrypt/750802ea0bc2d02fac93adeaa1398ec2/750802ea0bc2d...2-57d9518fae69
As far as I know there is a Key that needs to be entered in order to download the file.
And when I run the command in ffmpeg
I encounter many errors like:
Unable to open key file
Anyone who can download it.
I would be very happy if he would write me a code that works and explain to me how to do it
These are all the codes I have already tried
ffmpeg -decryption_key https://www.video-cdn.com/video/key/750802ea0bc2d02fac93adeaa13cde64 -i https://www.video-cdn.com/video/encrypt/750802ea0bc2d02fac93adeaa1398ec2/750802ea0bc2d02fac93adeaa1398ec2/video_720p.m3u8?token=R915dD-72351a7c-3dd1-4e58-b6c2-9cc813eeb183 -vcodec libx264 {output_file}
ffmpeg -decryption_key {key} -i {file} -max_muxing_queue_size 9999 d.mp4
ffmpeg -allowed_extensions ALL -protocol_whitelist data, file, http, https, tcp, tls, crypto -i "https://www.video-cdn.com/video/encrypt/f242d2da41d03b3955fb866efc5dbd59/f242d2da41d03b3955fb866efc5dbd59/video_720p.m3u8?token=R915dD-a1430cfc-0bda-46a0-a7e9-b15308875dc7" c copy -bsf: a aac_adtstoasc test.mp4 -decryption_key C:\ ffmpeg\enc.key
hlsdl -K "1a9625fb34a4afe0d5446138e9543563" https://www.video-cdn.com/video/encrypt/f242d2da41d03b3955fb866efc5dbd59/f242d2da41d03b3955fb866efc5dbd59/video_720p.m3u8?token=R915dD-be07b7e6-08aa-441b-afbd-5c7876409878
enter image description here
key:
base64:zPfjh0/g09EKjPIS4w37Kg==
Hex:ccf7e3874fe0d3d10a8cf212e30dfb2a
ffmpeg -decryption_key "https://www.video-cdn.com/video/key/750802ea0bc2d02fac93adeaa13cde64" -i "https://www.video-cdn.com/video/encrypt/750802ea0bc2d02fac93adeaa1398ec2/750802ea0bc2d02fac93adeaa1398ec2/video_720p.m3u8?token=R915dD-72351a7c-3dd1-4e58-b6c2-9cc813eeb183" -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 file.mp4

Error encrypting webm video with webm crypt

I'm trying to use the example here for Clearkey encryption for videos. As per the steps mentioned here I was able to download and build the encryption tool wemb_crypt but When I try to encrypt the file with
webm_crypt -i input.webm -o input-enc_bear1_0123456789012345.webm -video true -audio true -video_options content_id=0123456789012345,base_file=bear1.key -audio_options content_id=0123456789012345,base_file=bear1.key
I get this error
File: input.webm is not WebM file.Could not open WebM files.
Tried many different webm files with no luck.
Is there another way to encrypt clear key media with other tools? Any clue about the error above?
You can use ffmpeg and openssl to create an AES encrypted HLS stream - the ffmpeg documentation (http://ffmpeg.org/ffmpeg-all.html#Options-34) includes this example script:
#!/bin/sh
BASE_URL=${1:-'.'}
openssl rand 16 > file.key
echo $BASE_URL/file.key > file.keyinfo
echo file.key >> file.keyinfo
echo $(openssl rand -hex 16) >> file.keyinfo
ffmpeg -f lavfi -re -i testsrc -c:v h264 -hls_flags delete_segments \
-hls_key_info_file file.keyinfo out.m3u8
You can also use mp4Box (https://gpac.wp.imt.fr/mp4box/encryption/common-encryption/) to create basic clear DASH encryptions:
MP4Box -crypt drm_file.xml movie.mp4 -out movie_encrypted.mp4
The drm info is included in the drm_file.xml and is explained at the link above.

FFMPEG Encryption

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.
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

MPEG-TS audio synchronization lost on segmentation

I use FFmpeg for encoding my iphone video (on debian) and mediafilesegmenter (on mac OS server). For encoding this is my commande :
ffmpeg -i INPUT -y -acodec libfaac -ar 22000 -ab 40k -vcodec libx264 -b 600k \
-bt 600k -vpre slow -vpre baseline -threads 1 -level 30 -r 10 -s 400x224 \
-map_chapters -1:-1 -f ipod INPUT.mp4
When i read the INPUT.mp4 everything is OK with audio.
But when I use the Apple Segmenter (mediafilesegmenter) i have a descync between audio & video.
Is my command line is wrong ? or it's a Apple segmenter bug. The mediastreamvalidator show me :
WARNING: Media segment contains a video track but does not contain any IDR access unit with a SPS and a PPS
But i don't know if cause the audio desync.
I have the latest mediafilesegmenter download from connect.apple.com.

Using openssl encryption for Apple's HTTP Live Streaming

Has anyone had any luck getting encrypted streaming to work with Apple's HTTP Live Streaming using openssl? It seems I'm almost there but my video doesn't play but I don't get any errors in Safari either (like "Video is unplayable" or "You don't have permission to play this video" when I got the key wrong).
#bash script:
keyFile="key.txt"
openssl rand 16 > $keyFile
hexKey=$(cat key.txt | hexdump -e '"%x"')
hexIV='0'
openssl aes-128-cbc -e -in $fileName -out $encryptedFileName -p -nosalt -iv ${hexIV} -K ${hexKey}
#my playlist file:
#EXTM3U
#EXT-X-TARGETDURATION:000020
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key.txt"
#EXTINF:20, no desc
test.ts.enc
#EXT-X-ENDLIST
I was using these docs as a guide:
https://datatracker.ietf.org/doc/html/draft-pantos-http-live-streaming
Okay, I figured it out... My hexdump command was wrong. It should be:
hexKey=$(cat key.txt | hexdump -e '16/1 "%02x"')
Also keep in mind the following, if you have more than 1 TS "chunk", and you're looking for a bit-exact replacement for the Apple encryption pipeline. By default, the Apple encryption tool updates the IV (initialization vector) parameter for each of the chunks, which "increases the strength of the cipher," according to the Pantos spec.
Implementing this just means that the sequence number needs to be encoded in hex and passed as the -iv parameter to openssl:
#!/bin/bash
keyFile="key.txt"
openssl rand 16 > $keyFile
hexKey=$(cat key.txt | hexdump -e '"%x"')
# hexIV='0'
for i in {0..number_of_TS_chunks}
do
hexIV=`printf '%032x' $i`
openssl aes-128-cbc -e -in $fileName -out $encryptedFileName -p -nosalt -iv ${hexIV} -K ${hexKey}
done
Combining information from three of the above (the OP, the fix for hexdump and the IV information) yielded a working solution for us. Namely:
openssl rand 16 > static.key
key_as_hex=$(cat static.key | hexdump -e '16/1 "%02x"')
for i in {0..9}; do
init_vector=`printf '%032x' $i`
openssl aes-128-cbc -e -in video_low_$(($i+1)).ts -out video_low_enc_$(($i+1)).ts -p -nosalt -iv $init_vector -K $key_as_hex
done
Unfortunately I don't have the tools to experiment with this. It looks like you carefully followed the spec. One thing I would do is sniff the network do make sure the key.txt file is getting downloaded to Safari. I would also try explicitly picking the IV using the IV attribute of the EXT-X-KEY tag, e.g.
#EXT-X-KEY:METHOD=AES-128,URI="key.txt",IV=0x00000000000000000000000000000000

Resources