2

我是 Stackoverflow 的新手,这将是我的第一个问题。我的 HTML5 播放器在 Internet Explorer 上运行良好,但在 google chrome 上无法运行。我正在使用用 CENC 加密的 PlayReady 流。我怎样才能让它在 chrome 上工作?我无权访问服务器,它们由第三方运行。

谢谢

4

1 回答 1

3

从技术上讲,当您正在播放 PlayReady 时,可以支持 Widevine。这是可能的,因为您使用的是 CENC。由于您无法访问您提到的服务器,因此您可以使用一种称为 PSSH Forging 的技术。它基本上取代了部件,使 chrome 认为它是 Widevine,因为它是 CENC,CDM 将解密视频并播放流。

为了方便起见,我假设您使用 DASH。

我们这里有一个 PSSH Box:

const widevinePSSH = '0000005c7073736800000000edef8ba979d64acea3c827dcd51d21ed0000003c080112101c773709e5ab359cbed9512bc27755fa1a087573702d63656e63221848486333436557724e5a792b32564572776e64562b673d3d2a003200';

您需要1c773709e5ab359cbed9512bc27755fa用您的 KID 替换。

然后在您在 SourceBuffer 中插入分段的部分(在 appendSegment 之前),您可以执行以下操作:

let segment = args[0];

    segment = new Uint8Array(segment);
    const newPssh = widevinePSSH.replace('1c773709e5ab359cbed9512bc27755fa', psshKid);
    const subArray = new Uint8Array(DRMUtils.stringToArrayBuffer('70737368'));

    let index = 0;
    const found = subArray.every((item) => {
        const masterIndex = segment.indexOf(item, index);

        if (~masterIndex) {
            index = masterIndex;
            return true;
        }
    });

    if (found) {
        return originalSourceBufferAppendBuffer.apply(this, [].slice.call(args));
    }

    segment = DRMUtils.uInt8ArrayToHex(segment);

    // Inject the forged signal
    // 70737368 = pssh
    segment = segment.substr(0, segment.lastIndexOf('70737368') - 8) + newPssh + segment.substr(segment.lastIndexOf('70737368') - 8);

    // Fix the MOOV atom length
    // 6d6f6f76 = moov
    const header = segment.substr(0, segment.indexOf('6d6f6f76') - 8);
    const payload = segment.substr(segment.indexOf('6d6f6f76') - 8);
    const newLength = Math.floor(payload.length / 2);

    segment = header + DRMUtils.intToHex(newLength, 8) + payload.substr(8);

    segment = decode(segment).b;

可悲的是,我只能分享一些零碎的东西,但这大致是你应该做的让它工作。

于 2017-08-21T09:20:59.303 回答