@@ -100,7 +100,10 @@ export class LevelKey implements DecryptData {
100100 return false ;
101101 }
102102
103- public getDecryptData ( sn : number | 'initSegment' ) : LevelKey | null {
103+ public getDecryptData (
104+ sn : number | 'initSegment' ,
105+ levelKeys ?: { [ key : string ] : LevelKey | undefined } ,
106+ ) : LevelKey | null {
104107 if ( ! this . encrypted || ! this . uri ) {
105108 return null ;
106109 }
@@ -135,10 +138,19 @@ export class LevelKey implements DecryptData {
135138 return this ;
136139 }
137140
138- if ( this . pssh && this . keyId ) {
139- return this ;
141+ if ( this . keyId ) {
142+ // Handle case where key id is changed in KEY_LOADING event handler #7542#issuecomment-3305203929
143+ const assignedKeyId = keyUriToKeyIdMap [ this . uri ] ;
144+ if ( assignedKeyId && ! arrayValuesMatch ( this . keyId , assignedKeyId ) ) {
145+ LevelKey . setKeyIdForUri ( this . uri , this . keyId ) ;
146+ }
147+
148+ if ( this . pssh ) {
149+ return this ;
150+ }
140151 }
141152
153+ // Key bytes are signalled the KEYID attribute, typically only found on WideVine KEY tags
142154 // Initialize keyId if possible
143155 const keyBytes = convertDataUriToArrayBytes ( this . uri ) ;
144156 if ( keyBytes ) {
@@ -156,8 +168,11 @@ export class LevelKey implements DecryptData {
156168 }
157169 }
158170 if ( ! this . keyId ) {
159- const offset = keyBytes . length - 22 ;
160- this . keyId = keyBytes . subarray ( offset , offset + 16 ) ;
171+ this . keyId = getKeyIdFromPlayReadyKey ( levelKeys ) ;
172+ if ( ! this . keyId ) {
173+ const offset = keyBytes . length - 22 ;
174+ this . keyId = keyBytes . subarray ( offset , offset + 16 ) ;
175+ }
161176 }
162177 break ;
163178 case KeySystemFormats . PLAYREADY : {
@@ -189,13 +204,20 @@ export class LevelKey implements DecryptData {
189204
190205 // Default behavior: assign a new keyId for each uri
191206 if ( ! this . keyId || this . keyId . byteLength !== 16 ) {
192- let keyId = keyUriToKeyIdMap [ this . uri ] ;
207+ let keyId : Uint8Array < ArrayBuffer > | null | undefined =
208+ keyUriToKeyIdMap [ this . uri ] ;
193209 if ( ! keyId ) {
194- const val =
195- Object . keys ( keyUriToKeyIdMap ) . length % Number . MAX_SAFE_INTEGER ;
196- keyId = new Uint8Array ( 16 ) ;
197- const dv = new DataView ( keyId . buffer , 12 , 4 ) ; // Just set the last 4 bytes
198- dv . setUint32 ( 0 , val ) ;
210+ keyId = getKeyIdFromWidevineKey ( levelKeys ) ;
211+ if ( ! keyId ) {
212+ keyId = getKeyIdFromPlayReadyKey ( levelKeys ) ;
213+ if ( ! keyId ) {
214+ const val =
215+ Object . keys ( keyUriToKeyIdMap ) . length % Number . MAX_SAFE_INTEGER ;
216+ keyId = new Uint8Array ( 16 ) ;
217+ const dv = new DataView ( keyId . buffer , 12 , 4 ) ; // Just set the last 4 bytes
218+ dv . setUint32 ( 0 , val ) ;
219+ }
220+ }
199221 LevelKey . setKeyIdForUri ( this . uri , keyId ) ;
200222 }
201223 this . keyId = keyId ;
@@ -205,6 +227,29 @@ export class LevelKey implements DecryptData {
205227 }
206228}
207229
230+ function getKeyIdFromWidevineKey (
231+ levelKeys : { [ key : string ] : LevelKey | undefined } | undefined ,
232+ ) {
233+ const widevineKey = levelKeys ?. [ KeySystemFormats . WIDEVINE ] ;
234+ if ( widevineKey ) {
235+ return widevineKey . keyId ;
236+ }
237+ return null ;
238+ }
239+
240+ function getKeyIdFromPlayReadyKey (
241+ levelKeys : { [ key : string ] : LevelKey | undefined } | undefined ,
242+ ) {
243+ const playReadyKey = levelKeys ?. [ KeySystemFormats . PLAYREADY ] ;
244+ if ( playReadyKey ) {
245+ const playReadyKeyBytes = convertDataUriToArrayBytes ( playReadyKey . uri ) ;
246+ if ( playReadyKeyBytes ) {
247+ return parsePlayReadyWRM ( playReadyKeyBytes ) ;
248+ }
249+ }
250+ return null ;
251+ }
252+
208253function createInitializationVector ( segmentNumber : number ) {
209254 const uint8View = new Uint8Array ( 16 ) ;
210255 for ( let i = 12 ; i < 16 ; i ++ ) {
0 commit comments