diff --git a/src/compat/should_call_generate_request_before_buffering_media.ts b/src/compat/should_call_generate_request_before_buffering_media.ts new file mode 100644 index 00000000000..fc2622f5bb2 --- /dev/null +++ b/src/compat/should_call_generate_request_before_buffering_media.ts @@ -0,0 +1,19 @@ +/** + * (2024-07-23) We noticed issues with most devices relying on PlayReady when + * playing some contents with mix encrypted and clear contents (not with + * Canal+ own contents weirdly enough, yet with multiple other contents + * encoded/packaged differently). + * The issue fixed itself when we called the + * `MediaKeySession.prototype.generateRequest` EME API **BEFORE** any segment + * was buffered. + * @param {string} keySystem - The key system in use. + * @returns {boolean} + */ +export default function shouldCallGenerateRequestBeforeBufferingMedia( + keySystem: string, +): boolean { + if (keySystem.indexOf("playready") !== -1) { + return true; + } + return false; +} diff --git a/src/main_thread/decrypt/content_decryptor.ts b/src/main_thread/decrypt/content_decryptor.ts index 5aed88295b6..d41e6d1bc38 100644 --- a/src/main_thread/decrypt/content_decryptor.ts +++ b/src/main_thread/decrypt/content_decryptor.ts @@ -15,7 +15,12 @@ */ import type { ICustomMediaKeys, ICustomMediaKeySystemAccess } from "../../compat/eme"; -import eme, { getInitData } from "../../compat/eme"; +import eme, { closeSession, getInitData } from "../../compat/eme"; +import { + DUMMY_PLAY_READY_HEADER, + generatePlayReadyInitData, +} from "../../compat/generate_init_data"; +import shouldCallGenerateRequestBeforeBufferingMedia from "../../compat/should_call_generate_request_before_buffering_media"; import config from "../../config"; import { EncryptedMediaError, OtherError } from "../../errors"; import log from "../../log"; @@ -54,6 +59,7 @@ import { areSomeKeyIdsContainedIn, } from "./utils/key_id_comparison"; import type KeySessionRecord from "./utils/key_session_record"; +import performFakeGenerateRequest from "./utils/perform_fake_generate_request"; /** * Module communicating with the Content Decryption Module (or CDM) to be able @@ -291,6 +297,22 @@ export default class ContentDecryptor extends EventEmitter { + const session = mediaKeys.createSession(); + const initData = generatePlayReadyInitData(DUMMY_PLAY_READY_HEADER); + await session.generateRequest("cenc", initData); + closeSession(session).catch((err) => { + const error = err instanceof Error ? err : new Error("Unknown Error"); + log.warn("DRM: unable to close fake MediaKeySession", error); + }); +}