Skip to content

fix: parsing keyId for widevine drm #7415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

yajin2021
Copy link
Contributor

This PR will...

Parse keyId for widevine. PSSH box defines as follows:

aligned(8) class ProtectionSystemSpecificHeaderBox extends FullBox('pssh', version, flags=0)
{
    unsigned int(8)[16]                SystemID;
    if (version > 0)
    {
         unsigned int(32)              KID_count;
         {
             unsigned int(8)[16]       KID;
         } [KID_count];
    }
    unsigned int(32)                   DataSize;
    unsigned int(8)[DataSize]          Data;
}

The length of the DataSize and Data fields is not always 6. For widevine, it is defined in WidevineCencHeader.proto

Why is this Pull Request needed?

Parse KeyId for widevine correctly

Checklist

  • changes have been done against master branch, and PR does not conflict
  • new unit / functional tests have been added (whenever applicable)
  • API or design changes are documented in API.md

Comment on lines 145 to 153
if (!this.keyId && keyBytes) {
const results = parseMultiPssh(keyBytes.buffer);
if (results[0] && 'version' in results[0]) {
const psshData = results[0];
if (psshData?.kids?.[0]) {
this.keyId = psshData.kids[0];
}
}
}
Copy link
Collaborator

@robwalch robwalch Jul 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Remove unnecessary conditionals (no need to check keyBytes and results[0] or psshData? multiple times)
  2. keyId still needs to be set if kids were not parsed
Suggested change
if (!this.keyId && keyBytes) {
const results = parseMultiPssh(keyBytes.buffer);
if (results[0] && 'version' in results[0]) {
const psshData = results[0];
if (psshData?.kids?.[0]) {
this.keyId = psshData.kids[0];
}
}
}
if (!this.keyId) {
const results = parseMultiPssh(keyBytes.buffer);
const psshData = results[0];
if (psshData && 'version' in psshData && psshData.kids?.[0]) {
this.keyId = psshData.kids[0];
} else {
const offset = keyBytes.length - 22;
this.keyId = keyBytes.subarray(offset, offset + 16);
}
}
  • I considered making a similar change (use parseMultiPssh) in Fix Widevine KEYID parsing #7380, but I couldn't find examples of version 1 pssh with kids containing a key. In every example, the KEYID was in the playlist, so that clients don't need a protobuf parser. Most content available to me has version 0 wv pssh.

Do you have content where this fix is necessary?

Fixing the key id parsing from the pssh would require at least some protobuf parsing. That isn't something we should do when standard practice is to include the KEYID attribute. We can still take this fix, if you need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I still use v1.5.x, I added this modification. Parsing the value from KEYID tag in playlist first for v1.6.7, the problem will not occur. But the logic of parsing keyId from URI is still inaccurate. If the version of PSSH is 0, KEYID does not exist. The keyid obtained by offsetting 6 bytes is incorrect.
Because the license request requires a dynamic token, I cannot create a test stream with PSSH version 1 now. But I have a simple example for playlist. The version of PSSH is 1 and the length of DataSize and Data is 5.

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:292092204
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MAP:URI="ibOQs5Rcy/init_video_1100.m4s"
#EXT-X-PROGRAM-DATE-TIME:2025-07-15T04:20:26.012Z
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="data:text/plain;base64,AAAASHBzc2gBAAAA7e+LqXnWSs6jyCfc1R0h7QAAAAGqqqqqqqqqqqqqqqqqqqqhAAAAFAgBEhCqqqqqqqqqqqqqqqqqqqqh",KEYID=0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1,KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSIONS="1"
#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,KEYFORMAT="com.microsoft.playready",KEYFORMATVERSIONS="1",URI="data:text/plain;charset=UTF-16;base64,WAIAAAEAAQBOAjwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4AcQBxAHEAcQBxAHEAcQBxAHEAcQBxAHEAcQBxAHEAcQBxAHEAcQBxAG8AUQA9AD0APAAvAEsASQBEAD4APABMAEEAXwBVAFIATAA+AGgAdAB0AHAAOgAvAC8AcABsAGEAeQByAGUAYQBkAHkALgBkAGkAcgBlAGMAdAB0AGEAcABzAC4AbgBlAHQALwBwAHIALwBzAHYAYwAvAHIAaQBnAGgAdABzAG0AYQBuAGEAZwBlAHIALgBhAHMAbQB4ADwALwBMAEEAXwBVAFIATAA+ADwALwBEAEEAVABBAD4APAAvAFcAUgBNAEgARQBBAEQARQBSAD4A"
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092204.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092205.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092206.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092207.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092208.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092209.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092210.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092211.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092212.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092213.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092214.m4s
#EXTINF:6.000000,
ibOQs5Rcy/media_video_1100-292092215.m4s
#EXTINF:2.000000,
ibOQs5Rcy/media_video_1100-292092216.m4s
#EXT-X-ENDLIST

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants