带清除键的EME无法与S3中存储的加密音频文件的预签名URL一起使用

问题描述

我已按照以下实用指南使用明确的密钥实施了EME: https://www.html5rocks.com/tutorials/eme/basics/

我已经通过使用webm-encrypt npm软件包提供了密钥和webm音频文件来对音频进行了加密。我在明文密钥代码中使用的相同密钥对音频进行解密。当我在本地使用加密的音频文件时,将src设置为:

audio.src = './encrypted.webm'
另一方面,我将相同的加密文件存储在s3中。问题是,当我将音频src指向服务器api时,服务器api又将其重定向到加密音频文件的预签名s3 url,音频无法播放,并且在控制台中看到以下错误

无法生成许可请求TypeError:无法在“ MediaKeySession”上执行“ generateRequest”:initDataType参数为空。

audio元素不为null,并且也会触发加密事件,但是event.initData和event.initDataType均为空。不确定我在这里缺少什么。

main.js

    "use strict";

var KEY = new Uint8Array([
  0xeb,0xdd,0x62,0xf1,0x68,0x14,0xd2,0x7b,0xef,0x12,0x2a,0xfc,0xe4,0xae,0x3c,]);

var config = [
  {
    initDataTypes: ["webm"],videoCapabilities: [
      {
        contentType: 'video/webm; codecs="vp8"',},],audioCapabilities: [
      { contentType: 'audio/webm; codecs="opus"' },{ contentType: 'audio/webm; codecs="vorbis"' },];

var audio = document.querySelector("audio");

audio.addEventListener("encrypted",handleEncrypted,false);

createMediaKeys().then(() => {
    //src points to server api
  audio.src = "/api/audio?file=encrypted1.webm";
});

function createMediaKeys() {
  return navigator
    .requestMediaKeySystemAccess("org.w3.clearkey",config)
    .then((keySystemAccess) => {
      return keySystemAccess.createMediaKeys();
    })
    .then((mediaKeys) => {
      return audio.setMediaKeys(mediaKeys);
    })
    .catch(function (error) {
      console.error("Failed to set up MediaKeys",error);
    });
}

function handleEncrypted(event) {
  var session = audio.mediaKeys.createSession();
  session.addEventListener("message",handleMessage,false);
  // error occurs at this line
  session
    .generateRequest(event.initDataType,event.initData)
    .catch(function (error) {
      console.error("Failed to generate a license request",error);
    });
}

function handleMessage(event) {
  var license = generateLicense(event.message);
  var session = event.target;
  session.update(license).catch(function (error) {
    console.error("Failed to update the session",error);
  });
}

function toBase64(u8arr) {
  return btoa(String.fromCharCode.apply(null,u8arr))
    .replace(/\+/g,"-")
    .replace(/\//g,"_")
    .replace(/=*$/,"");
}

function generateLicense(message) {
  var request = JSON.parse(new TextDecoder().decode(message));
  console.assert(request.kids.length === 1);

  var keyObj = {
    kty: "oct",alg: "A128KW",kid: request.kids[0],k: toBase64(KEY),};
  return new TextEncoder().encode(
    JSON.stringify({
      keys: [keyObj],})
  );
}

index.html

<!DOCTYPE html>
<html>

<head>
    <Meta charset="UTF-8">
    <title>EME with Clear Key</title>
</head>

<body>

    <div id="audio-player">
        <audio controls>
            <p>This browser does not support the audio element.</p>
        </audio>
    </div>

    <script src="./main.js"></script>
</body>

</html>

server.js

app.get("/api/audio",(req,res) => {
  
  const params = {
    Bucket: "test",Key: req.query.file,};
  const url = AWSS3.getSignedUrl("getobject",params);
  res.setHeader("Cache-Control","public,max-age=0");

  return res.redirect(302,url);
});

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)