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..c68bee4b6e4 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"; @@ -291,6 +296,28 @@ export default class ContentDecryptor extends EventEmitter { + const error = err instanceof Error ? err : new Error("Unknown Error"); + log.warn("DRM: unable to close initial fake MediaKeySession", error); + }); + } catch (err) { + const error = err instanceof Error ? err : new Error("Unknown Error"); + log.warn("DRM: unable to fully perform fake generateRequest call", error); + } + } + + if (this._isStopped()) { + // We might be stopped since then + return; + } + const prevState = this._stateData.state; this._stateData = { state: ContentDecryptorState.ReadyForContent,