Happy so far
This commit is contained in:
parent
75b5d6e8ef
commit
c019e73625
@ -13,9 +13,9 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||||||
const { type, data } = message;
|
const { type, data } = message;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "INTERCEPTED_POST":
|
case "DRM_TYPE":
|
||||||
console.log("Storing POST Request", data);
|
console.log("DRM Type:", data);
|
||||||
chrome.storage.local.set({ latestLicenseRequest: data });
|
chrome.storage.local.set({ drmType: data });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "PSSH_DATA":
|
case "PSSH_DATA":
|
||||||
@ -23,26 +23,11 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||||||
chrome.storage.local.set({ latestPSSH: data });
|
chrome.storage.local.set({ latestPSSH: data });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "LICENSE_DATA":
|
|
||||||
console.log("Storing License Response:", data);
|
|
||||||
chrome.storage.local.set({ latestLicenseResponse: data });
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "CERTIFICATE_DATA":
|
|
||||||
console.log("Storing Service Certificate:", data);
|
|
||||||
chrome.storage.local.set({ latestServiceCertificate: data });
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "KEYS_DATA":
|
case "KEYS_DATA":
|
||||||
console.log("Storing Decryption Keys:", data);
|
console.log("Storing Decryption Keys:", data);
|
||||||
chrome.storage.local.set({ latestKeys: data });
|
chrome.storage.local.set({ latestKeys: data });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "DRM_TYPE":
|
|
||||||
console.log("DRM Type:", data);
|
|
||||||
chrome.storage.local.set({ drmType: data });
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.warn("Unknown message type received:", type);
|
console.warn("Unknown message type received:", type);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
window.addEventListener("message", function(event) {
|
window.addEventListener("message", function(event) {
|
||||||
if (event.source !== window) return;
|
if (event.source !== window) return;
|
||||||
|
|
||||||
if (["__INTERCEPTED_POST__", "__PSSH_DATA__", "__LICENSE_DATA__", "__CERTIFICATE_DATA__", "__KEYS_DATA__", "__DRM_TYPE__"].includes(event.data?.type)) {
|
if (["__DRM_TYPE__", "__PSSH_DATA__", "__KEYS_DATA__"].includes(event.data?.type)) {
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
type: event.data.type.replace("__", "").replace("__", ""),
|
type: event.data.type.replace("__", "").replace("__", ""),
|
||||||
data: event.data.data
|
data: event.data.data
|
||||||
|
312
inject.js
312
inject.js
@ -1,7 +1,17 @@
|
|||||||
let widevineDeviceInfo = null;
|
let widevineDeviceInfo = null;
|
||||||
let playreadyDeviceInfo = null;
|
let playreadyDeviceInfo = null;
|
||||||
|
let originalChallenge = null
|
||||||
|
let serviceCertFound = false;
|
||||||
|
let drmType = "NONE";
|
||||||
|
let psshFound = false;
|
||||||
|
let pssh = null;
|
||||||
let drmOverride = "DISABLED";
|
let drmOverride = "DISABLED";
|
||||||
let interceptType = "DISABLED";
|
let interceptType = "DISABLED";
|
||||||
|
let remoteCDM = null;
|
||||||
|
let generateRequestCalled = false;
|
||||||
|
let remoteListenerMounted = false;
|
||||||
|
let injectionSuccess = false;
|
||||||
|
let licenseResponseCounter = 0;
|
||||||
|
|
||||||
// Post message to content.js to get DRM override
|
// Post message to content.js to get DRM override
|
||||||
window.postMessage({ type: "__GET_DRM_OVERRIDE__" }, "*");
|
window.postMessage({ type: "__GET_DRM_OVERRIDE__" }, "*");
|
||||||
@ -59,16 +69,14 @@ class remotePlayReadyCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open PlayReady session
|
// Open PlayReady session
|
||||||
async openSession() {
|
openSession() {
|
||||||
const url = `${this.host}/remotecdm/playready/${this.device_name}/open`;
|
const url = `${this.host}/remotecdm/playready/${this.device_name}/open`;
|
||||||
const response = await fetch(url, {
|
const xhr = new XMLHttpRequest();
|
||||||
method: 'GET',
|
xhr.open('GET', url, false);
|
||||||
headers: {
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
'Content-Type': 'application/json',
|
xhr.send();
|
||||||
}
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
})
|
if (jsonData.data?.session_id) {
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok && jsonData.data?.session_id) {
|
|
||||||
this.session_id = jsonData.data.session_id;
|
this.session_id = jsonData.data.session_id;
|
||||||
console.log("PlayReady session opened:", this.session_id);
|
console.log("PlayReady session opened:", this.session_id);
|
||||||
} else {
|
} else {
|
||||||
@ -78,21 +86,18 @@ class remotePlayReadyCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get PlayReady challenge
|
// Get PlayReady challenge
|
||||||
async getChallenge(init_data) {
|
getChallenge(init_data) {
|
||||||
const url = `${this.host}/remotecdm/playready/${this.device_name}/get_license_challenge`;
|
const url = `${this.host}/remotecdm/playready/${this.device_name}/get_license_challenge`;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
const body = {
|
const body = {
|
||||||
session_id: this.session_id,
|
session_id: this.session_id,
|
||||||
init_data: init_data
|
init_data: init_data
|
||||||
};
|
};
|
||||||
const response = await fetch(url, {
|
xhr.send(JSON.stringify(body));
|
||||||
method: 'POST',
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
headers: {
|
if (jsonData.data?.challenge) {
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
});
|
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok && jsonData.data?.challenge) {
|
|
||||||
this.challenge = btoa(jsonData.data.challenge);
|
this.challenge = btoa(jsonData.data.challenge);
|
||||||
console.log("PlayReady challenge received:", this.challenge);
|
console.log("PlayReady challenge received:", this.challenge);
|
||||||
} else {
|
} else {
|
||||||
@ -102,21 +107,18 @@ class remotePlayReadyCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse PlayReady license response
|
// Parse PlayReady license response
|
||||||
async parseLicense(license_message) {
|
parseLicense(license_message) {
|
||||||
const url = `${this.host}/remotecdm/playready/${this.device_name}/parse_license`;
|
const url = `${this.host}/remotecdm/playready/${this.device_name}/parse_license`;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
const body = {
|
const body = {
|
||||||
session_id: this.session_id,
|
session_id: this.session_id,
|
||||||
license_message: license_message
|
license_message: license_message
|
||||||
}
|
}
|
||||||
const response = await fetch(url, {
|
xhr.send(JSON.stringify(body));
|
||||||
method: 'POST',
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
headers: {
|
if (jsonData.message === "Successfully parsed and loaded the Keys from the License message")
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
});
|
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok && jsonData.message === "Successfully parsed and loaded the Keys from the License message")
|
|
||||||
{
|
{
|
||||||
console.log("PlayReady license response parsed successfully");
|
console.log("PlayReady license response parsed successfully");
|
||||||
return true;
|
return true;
|
||||||
@ -127,20 +129,17 @@ class remotePlayReadyCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get PlayReady keys
|
// Get PlayReady keys
|
||||||
async getKeys() {
|
getKeys() {
|
||||||
const url = `${this.host}/remotecdm/playready/${this.device_name}/get_keys`;
|
const url = `${this.host}/remotecdm/playready/${this.device_name}/get_keys`;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
const body = {
|
const body = {
|
||||||
session_id: this.session_id
|
session_id: this.session_id
|
||||||
}
|
}
|
||||||
const response = await fetch(url, {
|
xhr.send(JSON.stringify(body));
|
||||||
method: 'POST',
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
headers: {
|
if (jsonData.data?.keys) {
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
});
|
|
||||||
const jsonData = await response.json()
|
|
||||||
if (response.ok && jsonData.data?.keys) {
|
|
||||||
this.keys = jsonData.data.keys;
|
this.keys = jsonData.data.keys;
|
||||||
console.log("PlayReady keys received:", this.keys);
|
console.log("PlayReady keys received:", this.keys);
|
||||||
} else {
|
} else {
|
||||||
@ -150,16 +149,14 @@ class remotePlayReadyCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close PlayReady session
|
// Close PlayReady session
|
||||||
async closeSession () {
|
closeSession () {
|
||||||
const url = `${this.host}/remotecdm/playready/${this.device_name}/close/${this.session_id}`;
|
const url = `${this.host}/remotecdm/playready/${this.device_name}/close/${this.session_id}`;
|
||||||
const response = await fetch(url, {
|
const xhr = new XMLHttpRequest();
|
||||||
method: 'GET',
|
xhr.open('GET', url, false);
|
||||||
headers: {
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
'Content-Type': 'application/json',
|
xhr.send();
|
||||||
}
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
});
|
if (jsonData) {
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok) {
|
|
||||||
console.log("PlayReady session closed successfully");
|
console.log("PlayReady session closed successfully");
|
||||||
} else {
|
} else {
|
||||||
console.error("Failed to close PlayReady session:", jsonData.message);
|
console.error("Failed to close PlayReady session:", jsonData.message);
|
||||||
@ -183,7 +180,7 @@ class remoteWidevineCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open Widevine session
|
// Open Widevine session
|
||||||
async openSession () {
|
openSession () {
|
||||||
const url = `${this.host}/remotecdm/widevine/${this.device_name}/open`;
|
const url = `${this.host}/remotecdm/widevine/${this.device_name}/open`;
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
xhr.open('GET', url, false);
|
xhr.open('GET', url, false);
|
||||||
@ -200,21 +197,18 @@ class remoteWidevineCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set Widevine service certificate
|
// Set Widevine service certificate
|
||||||
async setServiceCertificate(certificate) {
|
setServiceCertificate(certificate) {
|
||||||
const url = `${this.host}/remotecdm/widevine/${this.device_name}/set_service_certificate`;
|
const url = `${this.host}/remotecdm/widevine/${this.device_name}/set_service_certificate`;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
const body = {
|
const body = {
|
||||||
session_id: this.session_id,
|
session_id: this.session_id,
|
||||||
certificate: certificate ?? null
|
certificate: certificate ?? null
|
||||||
}
|
}
|
||||||
const response = await fetch(url, {
|
xhr.send(JSON.stringify(body));
|
||||||
method: 'POST',
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
headers: {
|
if (jsonData.status === 200) {
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
});
|
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok && jsonData.status === 200) {
|
|
||||||
console.log("Service certificate set successfully");
|
console.log("Service certificate set successfully");
|
||||||
} else {
|
} else {
|
||||||
console.error("Failed to set service certificate:", jsonData.message);
|
console.error("Failed to set service certificate:", jsonData.message);
|
||||||
@ -223,22 +217,19 @@ class remoteWidevineCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get Widevine challenge
|
// Get Widevine challenge
|
||||||
async getChallenge(init_data, license_type = 'STREAMING') {
|
getChallenge(init_data, license_type = 'STREAMING') {
|
||||||
const url = `${this.host}/remotecdm/widevine/${this.device_name}/get_license_challenge/${license_type}`;
|
const url = `${this.host}/remotecdm/widevine/${this.device_name}/get_license_challenge/${license_type}`;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
const body = {
|
const body = {
|
||||||
session_id: this.session_id,
|
session_id: this.session_id,
|
||||||
init_data: init_data,
|
init_data: init_data,
|
||||||
privacy_mode: serviceCertFound
|
privacy_mode: serviceCertFound
|
||||||
};
|
};
|
||||||
const response = await fetch(url, {
|
xhr.send(JSON.stringify(body));
|
||||||
method: 'POST',
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
headers: {
|
if (jsonData.data?.challenge_b64) {
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
});
|
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok && jsonData.data?.challenge_b64) {
|
|
||||||
this.challenge = jsonData.data.challenge_b64;
|
this.challenge = jsonData.data.challenge_b64;
|
||||||
console.log("Widevine challenge received:", this.challenge);
|
console.log("Widevine challenge received:", this.challenge);
|
||||||
} else {
|
} else {
|
||||||
@ -248,21 +239,18 @@ class remoteWidevineCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse Widevine license response
|
// Parse Widevine license response
|
||||||
async parseLicense(license_message) {
|
parseLicense(license_message) {
|
||||||
const url = `${this.host}/remotecdm/widevine/${this.device_name}/parse_license`;
|
const url = `${this.host}/remotecdm/widevine/${this.device_name}/parse_license`;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
const body = {
|
const body = {
|
||||||
session_id: this.session_id,
|
session_id: this.session_id,
|
||||||
license_message: license_message
|
license_message: license_message
|
||||||
};
|
};
|
||||||
const response = await fetch(url, {
|
xhr.send(JSON.stringify(body));
|
||||||
method: 'POST',
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
headers: {
|
if (jsonData.status === 200) {
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
});
|
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok && jsonData.status === 200) {
|
|
||||||
console.log("Widevine license response parsed successfully");
|
console.log("Widevine license response parsed successfully");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -272,20 +260,17 @@ class remoteWidevineCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get Widevine keys
|
// Get Widevine keys
|
||||||
async getKeys() {
|
getKeys() {
|
||||||
const url = `${this.host}/remotecdm/widevine/${this.device_name}/get_keys/ALL`;
|
const url = `${this.host}/remotecdm/widevine/${this.device_name}/get_keys/ALL`;
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url, false);
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
const body = {
|
const body = {
|
||||||
session_id: this.session_id
|
session_id: this.session_id
|
||||||
};
|
};
|
||||||
const response = await fetch(url, {
|
xhr.send(JSON.stringify(body));
|
||||||
method: 'POST',
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
headers: {
|
if (jsonData.data?.keys) {
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body)
|
|
||||||
});
|
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok && jsonData.data?.keys) {
|
|
||||||
this.keys = jsonData.data.keys;
|
this.keys = jsonData.data.keys;
|
||||||
console.log("Widevine keys received:", this.keys);
|
console.log("Widevine keys received:", this.keys);
|
||||||
} else {
|
} else {
|
||||||
@ -295,16 +280,14 @@ class remoteWidevineCDM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close Widevine session
|
// Close Widevine session
|
||||||
async closeSession() {
|
closeSession() {
|
||||||
const url = `${this.host}/remotecdm/widevine/${this.device_name}/close/${this.session_id}`;
|
const url = `${this.host}/remotecdm/widevine/${this.device_name}/close/${this.session_id}`;
|
||||||
const response = await fetch(url, {
|
const xhr = new XMLHttpRequest();
|
||||||
method: 'GET',
|
xhr.open('GET', url, false);
|
||||||
headers: {
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
'Content-Type': 'application/json',
|
xhr.send();
|
||||||
}
|
const jsonData = JSON.parse(xhr.responseText);
|
||||||
});
|
if (jsonData) {
|
||||||
const jsonData = await response.json();
|
|
||||||
if (response.ok) {
|
|
||||||
console.log("Widevine session closed successfully");
|
console.log("Widevine session closed successfully");
|
||||||
} else {
|
} else {
|
||||||
console.error("Failed to close Widevine session:", jsonData.message);
|
console.error("Failed to close Widevine session:", jsonData.message);
|
||||||
@ -416,3 +399,136 @@ function arrayBufferToBase64(uint8array) {
|
|||||||
|
|
||||||
return window.btoa(binary);
|
return window.btoa(binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Challenge messahe interceptor
|
||||||
|
const originalGenerateRequest = MediaKeySession.prototype.generateRequest;
|
||||||
|
MediaKeySession.prototype.generateRequest = function(initDataType, initData) {
|
||||||
|
if (!generateRequestCalled) {
|
||||||
|
generateRequestCalled = true;
|
||||||
|
const session = this;
|
||||||
|
let playReadyPssh = getPlayReadyPssh(initData);
|
||||||
|
if (playReadyPssh && drmOverride !== "WIDEVINE") {
|
||||||
|
// PlayReady Code
|
||||||
|
drmType = "PlayReady";
|
||||||
|
window.postMessage({ type: "__DRM_TYPE__", data: "PlayReady" }, "*");
|
||||||
|
console.log("[DRM Detected] PlayReady");
|
||||||
|
pssh = playReadyPssh;
|
||||||
|
window.postMessage({ type: "__PSSH_DATA__", data: playReadyPssh }, "*");
|
||||||
|
console.log("[PlayReady PSSH found] " + playReadyPssh)
|
||||||
|
}
|
||||||
|
let wideVinePssh = getWidevinePssh(initData)
|
||||||
|
if (wideVinePssh && !playReadyPssh && drmOverride !== "PLAYREADY") {
|
||||||
|
// Widevine code
|
||||||
|
drmType = "Widevine";
|
||||||
|
window.postMessage({ type: "__DRM_TYPE__", data: "Widevine" }, "*");
|
||||||
|
console.log("[DRM Detected] Widevine");
|
||||||
|
pssh = wideVinePssh;
|
||||||
|
window.postMessage({ type: "__PSSH_DATA__", data: wideVinePssh }, "*");
|
||||||
|
console.log("[Widevine PSSH found] " + wideVinePssh)
|
||||||
|
}
|
||||||
|
if (!remoteListenerMounted) {
|
||||||
|
remoteListenerMounted = true;
|
||||||
|
session.addEventListener("message", function messageInterceptor(event) {
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
const uint8Array = new Uint8Array(event.message);
|
||||||
|
const base64challenge = arrayBufferToBase64(uint8Array);
|
||||||
|
if (base64challenge === "CAQ=" && interceptType !== "DISABLED" && drmOverride !== "PLAYREADY") {
|
||||||
|
const {
|
||||||
|
device_type, system_id, security_level, host, secret, device_name
|
||||||
|
} = widevineDeviceInfo;
|
||||||
|
remoteCDM = new remoteWidevineCDM(device_type, system_id, security_level, host, secret, device_name);
|
||||||
|
remoteCDM.openSession();
|
||||||
|
}
|
||||||
|
if (!injectionSuccess && base64challenge !== "CAQ=" && interceptType !== "DISABLED") {
|
||||||
|
if (interceptType === "EME") {
|
||||||
|
injectionSuccess = true;
|
||||||
|
}
|
||||||
|
if (!originalChallenge) {
|
||||||
|
originalChallenge = base64challenge;
|
||||||
|
}
|
||||||
|
if (!remoteCDM && drmType === "Widevine" && drmOverride !== "PLAYREADY") {
|
||||||
|
const {
|
||||||
|
device_type, system_id, security_level, host, secret, device_name
|
||||||
|
} = widevineDeviceInfo;
|
||||||
|
remoteCDM = new remoteWidevineCDM(device_type, system_id, security_level, host, secret, device_name);
|
||||||
|
remoteCDM.openSession();
|
||||||
|
}
|
||||||
|
if (!remoteCDM && drmType === "PlayReady" && drmOverride !== "WIDEVINE") {
|
||||||
|
const {
|
||||||
|
security_level, host, secret, device_name
|
||||||
|
} = playreadyDeviceInfo;
|
||||||
|
remoteCDM = new remotePlayReadyCDM(security_level, host, secret, device_name)
|
||||||
|
remoteCDM.openSession();
|
||||||
|
}
|
||||||
|
if (remoteCDM) {
|
||||||
|
remoteCDM.getChallenge(pssh);
|
||||||
|
}
|
||||||
|
if (interceptType === "EME" && remoteCDM) {
|
||||||
|
const uint8challenge = base64ToUint8Array(remoteCDM.challenge);
|
||||||
|
const challengeBuffer = uint8challenge.buffer;
|
||||||
|
const syntheticEvent = new MessageEvent("message", {
|
||||||
|
data: event.data,
|
||||||
|
origin: event.origin,
|
||||||
|
lastEventId: event.lastEventId,
|
||||||
|
source: event.source,
|
||||||
|
ports: event.ports
|
||||||
|
});
|
||||||
|
Object.defineProperty(syntheticEvent, "message", {
|
||||||
|
get: () => challengeBuffer
|
||||||
|
});
|
||||||
|
console.log("Intercepted EME Challenge and injected custom one.")
|
||||||
|
session.dispatchEvent(syntheticEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log("Message interceptor mounted.");
|
||||||
|
}
|
||||||
|
return originalGenerateRequest.call(session, initDataType, initData);
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
// Message update interceptors
|
||||||
|
const originalUpdate = MediaKeySession.prototype.update;
|
||||||
|
MediaKeySession.prototype.update = function(response) {
|
||||||
|
const uint8 = response instanceof Uint8Array ? response : new Uint8Array(response);
|
||||||
|
const base64Response = window.btoa(String.fromCharCode(...uint8));
|
||||||
|
console.log(base64Response);
|
||||||
|
if (base64Response.startsWith("CAUS") && pssh && remoteCDM) {
|
||||||
|
remoteCDM.setServiceCertificate(base64Response);
|
||||||
|
}
|
||||||
|
if (!base64Response.startsWith("CAUS") && pssh) {
|
||||||
|
if (licenseResponseCounter === 1 && interceptType === "EME") {
|
||||||
|
remoteCDM.parseLicense(base64Response);
|
||||||
|
remoteCDM.getKeys();
|
||||||
|
remoteCDM.closeSession();
|
||||||
|
window.postMessage({ type: "__KEYS_DATA__", data: remoteCDM.keys }, "*");
|
||||||
|
}
|
||||||
|
licenseResponseCounter++;
|
||||||
|
}
|
||||||
|
const updatePromise = originalUpdate.call(this, response);
|
||||||
|
if (!pssh) {
|
||||||
|
updatePromise
|
||||||
|
.then(() => {
|
||||||
|
let clearKeys = getClearkey(response);
|
||||||
|
if (clearKeys && clearKeys.length > 0) {
|
||||||
|
console.log("[CLEARKEY] ", clearKeys);
|
||||||
|
const drmType = {
|
||||||
|
type: "__DRM_TYPE__",
|
||||||
|
data: 'ClearKey'
|
||||||
|
};
|
||||||
|
window.postMessage(drmType, "*");
|
||||||
|
const keysData = {
|
||||||
|
type: "__KEYS_DATA__",
|
||||||
|
data: clearKeys
|
||||||
|
};
|
||||||
|
window.postMessage(keysData, "*");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.log("[CLEARKEY] Not found");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user