@@ -12,6 +12,7 @@ import {
1212 removeEventListener ,
1313} from '../utils/event-listener-helper' ;
1414import { arrayToHex } from '../utils/hex' ;
15+ import { changeEndianness } from '../utils/keysystem-util' ;
1516import { Logger } from '../utils/logger' ;
1617import {
1718 getKeySystemsForConfig ,
@@ -881,6 +882,10 @@ class EMEController extends Logger implements ComponentAPI {
881882 const sessionLevelKeyId = arrayToHex (
882883 new Uint8Array ( mediaKeySessionContext . decryptdata . keyId || [ ] ) ,
883884 ) ;
885+
886+ let hasMatchedKey = false ;
887+ const keyStatuses : { status : MediaKeyStatus ; keyId : string } [ ] = [ ] ;
888+
884889 mediaKeySessionContext . mediaKeysSession . keyStatuses . forEach (
885890 ( status : MediaKeyStatus , keyId : BufferSource ) => {
886891 // keyStatuses.forEach is not standard API so the callback value looks weird on xboxone
@@ -890,27 +895,79 @@ class EMEController extends Logger implements ComponentAPI {
890895 keyId = status ;
891896 status = temp ;
892897 }
893- const keyIdWithStatusChange = arrayToHex (
898+
899+ const keyIdArray : Uint8Array =
894900 'buffer' in keyId
895901 ? new Uint8Array ( keyId . buffer , keyId . byteOffset , keyId . byteLength )
896- : new Uint8Array ( keyId ) ,
902+ : new Uint8Array ( keyId ) ;
903+
904+ // Handle PlayReady little-endian key ID conversion for status comparison only
905+ // Don't modify the original key ID from playlist parsing
906+ if (
907+ mediaKeySessionContext . keySystem === KeySystems . PLAYREADY &&
908+ keyIdArray . length === 16
909+ ) {
910+ changeEndianness ( keyIdArray ) ;
911+ }
912+
913+ const keyIdWithStatusChange = arrayToHex (
914+ keyIdArray as Uint8Array < ArrayBuffer > ,
897915 ) ;
898916
917+ // Store all key statuses for processing
918+ keyStatuses . push ( { status, keyId : keyIdWithStatusChange } ) ;
919+
899920 // Error immediately when encountering a key ID with this status again
900921 if ( status === 'internal-error' ) {
901922 this . bannedKeyIds [ keyIdWithStatusChange ] = status ;
902923 }
903924
904- // Only acknowledge status changes for level- key ID
925+ // Check if this key matches the session-level key ID
905926 const matched = keyIdWithStatusChange === sessionLevelKeyId ;
906- this . log (
907- `${ matched ? '' : 'un' } matched key status change "${ status } " for keyStatuses keyId: ${ keyIdWithStatusChange } session keyId: ${ sessionLevelKeyId } uri: ${ mediaKeySessionContext . decryptdata . uri } ` ,
908- ) ;
909927 if ( matched ) {
928+ hasMatchedKey = true ;
910929 mediaKeySessionContext . keyStatus = status ;
930+ this . log (
931+ `matched key status change "${ status } " for keyStatuses keyId: ${ keyIdWithStatusChange } session keyId: ${ sessionLevelKeyId } uri: ${ mediaKeySessionContext . decryptdata . uri } ` ,
932+ ) ;
933+ } else {
934+ this . log (
935+ `unmatched key status change "${ status } " for keyStatuses keyId: ${ keyIdWithStatusChange } session keyId: ${ sessionLevelKeyId } uri: ${ mediaKeySessionContext . decryptdata . uri } ` ,
936+ ) ;
911937 }
912938 } ,
913939 ) ;
940+
941+ // Handle case where no keys matched but all have the same status
942+ // This can happen with PlayReady when key IDs don't align properly
943+ if ( ! hasMatchedKey && keyStatuses . length > 0 ) {
944+ const firstStatus = keyStatuses [ 0 ] . status ;
945+ const allSameStatus = ! keyStatuses . some (
946+ ( { status } ) => status !== firstStatus ,
947+ ) ;
948+
949+ if (
950+ allSameStatus &&
951+ ( firstStatus === 'usable' || firstStatus . startsWith ( 'usable' ) )
952+ ) {
953+ this . log (
954+ `No key matched session keyId ${ sessionLevelKeyId } , but all keys have usable status "${ firstStatus } ". Treating as usable.` ,
955+ ) ;
956+ mediaKeySessionContext . keyStatus = firstStatus ;
957+ } else if (
958+ allSameStatus &&
959+ ( firstStatus === 'internal-error' || firstStatus === 'expired' )
960+ ) {
961+ this . log (
962+ `No key matched session keyId ${ sessionLevelKeyId } , but all keys have error status "${ firstStatus } ". Applying to session.` ,
963+ ) ;
964+ mediaKeySessionContext . keyStatus = firstStatus ;
965+ } else {
966+ this . log (
967+ `No key matched session keyId ${ sessionLevelKeyId } . Key statuses: ${ keyStatuses . map ( ( { keyId, status } ) => `${ keyId } :${ status } ` ) . join ( ', ' ) } ` ,
968+ ) ;
969+ }
970+ }
914971 }
915972
916973 private fetchServerCertificate (
0 commit comments