shaka-project / shaka-streamer

A simple config-file based approach to preparing streaming media, based on FFmpeg and Shaka Packager.
https://shaka-project.github.io/shaka-streamer/
Apache License 2.0
198 stars 62 forks source link

How to create Clear Key HLS #144

Open Chokoabigail opened 10 months ago

Chokoabigail commented 10 months ago

This issue was under opus - I deleted it from there and reposted it with its own thread so it wouldn't confuse others.

I want to add simple encryption to the generated HLS, The encryption should work on all major browsers (including IOS, Safari, Chrome, Edge, etc.), After research, I understand that I'm looking for a Clear Key encryption with a server key so the browser asks the server to give the key and decrypt the fragments.

In the end, we should get something like this: HLS AES-128/ClearKey - and this should work on all browsers.

This is the pipeline.yaml I tried:

streaming_mode: vod
resolutions:
  - 360p

channel_layouts:
  - stereo
  - surround

manifest_format:
  - hls

segment_size: 10

segment_per_file: True

encryption:
  enable: True

  encryption_mode: raw
  protection_systems:
    - CommonSystem
  keys:
    - key_id: 8858d6731bee84d3b6e3d12f3c767a26
      key: 1ae8ccd0e7985cc0b6203a55855a1034
  iv: "00000000000000000000000000000000"
  key_server_url: https://www.httpstest.com:616/mykey.secret
  protection_scheme: cbcs
  clear_lead: 0

I edited the shaka-streamer code here: https://github.com/shaka-project/shaka-streamer/blob/f2d3445e4582cd21ec5ae5143549f744e91d5e86/streamer/packager_node.py#L238 and added the following to support key_server_url:

      if encryption.key_server_url:
        args.extend(['--hls_key_uri', encryption.key_server_url])

to have support in hls_key_uri.

The problem is, I get the following m3u8 file:

#EXTM3U
#EXT-X-VERSION:6
## Generated with https://github.com/google/shaka-packager version v2.6.1-634af65-release
#EXT-X-TARGETDURATION:13
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="video_360p_400k_h264_init.mp4"
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="https://www.httpstest.com:616/mykey.secret",IV=0x00000000000000000000000000000000,KEYFORMAT="identity"
#EXTINF:10.969,
video_360p_400k_h264_1.mp4
#EXTINF:12.054,
video_360p_400k_h264_2.mp4
#EXTINF:10.552,
video_360p_400k_h264_3.mp4
#EXTINF:11.553,
video_360p_400k_h264_4.mp4
#EXTINF:5.672,
video_360p_400k_h264_5.mp4
#EXTINF:9.259,
video_360p_400k_h264_6.mp4
#EXT-X-ENDLIST

and when I try to load it in https://shaka-player-demo.appspot.com/demo/#audiolang=en-US;textlang=en-US;uilang=en-US;panel=CUSTOM%20CONTENT;build=uncompiled I get the following error: [Shaka Error DRM.REQUESTED_KEY_SYSTEM_CONFIG_UNAVAILABLE ()](https://shaka-player-demo.appspot.com/docs/api/shaka.util.Error.html#value:6001). I tried it on a Chrome browser on a Windows 11 machine.

I'm not sure what I do rung, can you help me, please?

----- update with player configuration ----

When I configure the shaka player like this:

const manifestUri =
    'https://www.httpstest.com:616/hls.m3u8';

function initApp() {
  shaka.log.setLevel(shaka.log.Level.V2); 
  shaka.polyfill.installAll();

  if (shaka.Player.isBrowserSupported()) {
    initPlayer();
  } else {
    console.error('Browser not supported!');
  }
}

async function initPlayer() {
  const video = document.getElementById('video');
  const player = new shaka.Player(video);

  player.configure({
  drm: {
    clearKeys: {
      // 'key-id-in-hex': 'key-in-hex',
      '8858d6731bee84d3b6e3d12f3c767a26': '1ae8ccd0e7985cc0b6203a55855a1034'
    },
  }
});

  window.player = player;
  player.addEventListener('error', onErrorEvent);

  try {
    await player.load(manifestUri);
    console.log('The video has now been loaded!');
  } catch (e) {
    onError(e);
  }
}

function onErrorEvent(event) {
  onError(event.detail);
}

function onError(error) {
  console.error('Error code', error.code, 'object', error);
}

document.addEventListener('DOMContentLoaded', initApp);

The video is played.

In addition, when I switch the drm configuration to:

servers: {
      'org.w3.clearkey': 'https://www.httpstest.com:616/key.key'
    }

I can also see the video (the player sends a request to get the key, and gets in response: { "keys": [ { "k": "GujM0OeYXMC2IDpVhVoQNA", "kty": "oct", "kid": "iFjWcxvuhNO249EvPHZ6Jg" } ], "type": "temporary" } and play the video.

When I don't configure the player with drm at all, I get: "Shaka Error DRM.ENCRYPTED_CONTENT_WITHOUT_DRM_INFO ()" and the player does not try to send a request for the key at all.