Video Streaming

How video
encryption/decryption works

Private files, that can be accessed only by particular NFT owners

How does it work?

When a user uploads a video via the Freeport Creator Suite UI and Freeport Creator Suite API, it is encoded using HLS into streamable chunks. Each chunk is then encrypted and stored in the DDC. This process is supported out of the box by the Media SDK

Key Derivation

Each video file gets an individual DEK (Encryption/Decryption Key) derived from a Master DEK which is used to encrypt and decrypt the video. Each chunk also gets it’s own individual DEK which is derived from the Video DEK using a nonce.

Client Side Video Decryption

To decrypt a video on the client-side, the user must first request the DEK for the video that they wish to decrypt. The decryption process is supported out of the box via the EncryptedVideoPlayer component

  1. Fetch the Video DEK associated with the content being retrieved
  2. Fetch the root playlist file from the DDC (not encrypted)
  3. Fetch the playlist file for the associated quality that is desired (not encrypted)
  4. For each chunk, the nonce for the DEK is encoded in the chunk name as chunk/enc_<nonce>_<cid> , for example:
    1. chunk/enc_0x01decbcb3f8908d885b5a5663c8786f73c240dc4ed94df55_baebb4iddto7txzjtxwsmriyghknrrzhcnjroevdlngcmdllb7orluhl4wy
  5. The DEK for the chunk can be calculated using a Blake2 Hash

const seed = new Uint8Array(nonce.length + masterDek.length);


   seed.set(masterDek, nonce.length);

   return this.blake2AsU8a(seed);

6. The DEK for the chunk can be calculated using a Blake2 Hash

const videoDek = // fetch video DEK

   const derivedDek = deriveDek(nonce, videoDek); // as above

   const result = naclDecrypt(data, nonce, derivedDek);

Server Side Encryption

If client side encryption cannot be done, the same process as above is executed on the server side, and the decrypted content is streamed directly to the user. To enable server-side streaming on most devices, a streamKey solution is used.

This is supported using the EncryptedVideoPlayer with the serverside property enabled

How to show case it?

This is more advanced option that can be also used on top of the Cere stack. High-level steps should be taken to achieve the goal: