mirror of
https://github.com/ThatNotEasy/PlayReadyProxy.git
synced 2026-04-02 02:29:38 +00:00
Add files via upload
This commit is contained in:
committed by
GitHub
parent
c88b4d9068
commit
4864a787be
145
panel/panel.css
Normal file
145
panel/panel.css
Normal file
@@ -0,0 +1,145 @@
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #ffffff;
|
||||
color: black;
|
||||
width: 400px;
|
||||
}
|
||||
.toggleButton {
|
||||
width: 24px;
|
||||
}
|
||||
select {
|
||||
max-width: 330px;
|
||||
}
|
||||
.text-box {
|
||||
outline: none;
|
||||
width: 80%;
|
||||
}
|
||||
#downloader-name {
|
||||
width: 160px;
|
||||
}
|
||||
#export {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/* Dark mode */
|
||||
.dark-mode {
|
||||
background-color: #1b1b1b;
|
||||
color: #d5d5d5;
|
||||
}
|
||||
.dark-mode fieldset {
|
||||
border-color: #535353;
|
||||
}
|
||||
.dark-mode button,
|
||||
.dark-mode select {
|
||||
background-color: #222;
|
||||
color: #d5d5d5;
|
||||
}
|
||||
.dark-mode button:hover,
|
||||
.dark-mode select:hover {
|
||||
background-color: #323232;
|
||||
}
|
||||
.dark-mode .expandableDiv {
|
||||
background-color: #1b2027;
|
||||
}
|
||||
.dark-mode .text-box {
|
||||
background-color: #323232;
|
||||
color: #d5d5d5;
|
||||
}
|
||||
|
||||
/* Switch */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Slider */
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
transition: 0.4s;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
}
|
||||
input:checked + .slider {
|
||||
background-color: #2196f3;
|
||||
}
|
||||
input:checked + .slider:before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
#clear {
|
||||
width: 100%;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
#type-select {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#settings {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.header > * {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#remote {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.log-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.right-bound {
|
||||
text-align: right;
|
||||
}
|
||||
.expandableDiv {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background-color: lightblue;
|
||||
padding: 0;
|
||||
}
|
||||
.expandableDiv.expanded {
|
||||
padding: 5px;
|
||||
}
|
||||
.expandableDiv.collapsed {
|
||||
padding: 0;
|
||||
}
|
||||
.always-visible {
|
||||
display: block;
|
||||
}
|
||||
.expanded-only {
|
||||
display: none;
|
||||
}
|
||||
.expandableDiv.expanded .expanded-only {
|
||||
display: block;
|
||||
}
|
||||
98
panel/panel.html
Normal file
98
panel/panel.html
Normal file
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Playready Proxy Settings</title>
|
||||
<script type="module" src="panel.js" defer></script>
|
||||
<link rel="stylesheet" href="panel.css" />
|
||||
</head>
|
||||
<body class="dark-mode" style="min-width: 200px">
|
||||
<div class="header">
|
||||
<img
|
||||
src="../images/icon-128.png"
|
||||
alt="PlayreadyProxy Icon"
|
||||
width="64"
|
||||
/>
|
||||
<img
|
||||
src="../images/proxy_text.png"
|
||||
alt="ProxyText"
|
||||
width="200"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<legend>Settings</legend>
|
||||
<div id="settings">
|
||||
<!-- Enabled -->
|
||||
<div>
|
||||
<input type="checkbox" id="enabled" />
|
||||
<label for="enabled"> Enabled</label>
|
||||
</div>
|
||||
<!-- Dark mode -->
|
||||
</div>
|
||||
|
||||
<fieldset id="remote">
|
||||
<legend>Remote CDM</legend>
|
||||
<button type="button" id="remoteInput">
|
||||
Choose Config
|
||||
</button>
|
||||
<button type="button" id="remoteRemove">Remove</button>
|
||||
<button type="button" id="remoteDownload">Download</button><br />
|
||||
<label for="remote-combobox">
|
||||
Select Config:
|
||||
<select id="remote-combobox"></select>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="local">
|
||||
<legend>Local CDM</legend>
|
||||
<button type="button" id="localInput">
|
||||
Choose Device
|
||||
</button>
|
||||
<button type="button" id="localRemove">Remove</button>
|
||||
<button type="button" id="localDownload">Download</button><br />
|
||||
<label for="local-combobox">
|
||||
Select Device:
|
||||
<select id="local-combobox"></select>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="proxy-settings">
|
||||
<legend>Proxy Settings</legend>
|
||||
<div>
|
||||
<input type="checkbox" id="enable-proxy" />
|
||||
<label for="enable-proxy">Enable Proxy</label>
|
||||
</div>
|
||||
<div id="proxy-config" style="display: none;">
|
||||
<label for="proxy-url">Proxy URL: </label>
|
||||
<input type="text" class="text-box" id="proxy-url" placeholder="http://your.proxy.url:port" />
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset id="command-options">
|
||||
<legend>Command Options</legend>
|
||||
<div>
|
||||
<input type="checkbox" id="use-shaka" /> <!-- Unchecked by default -->
|
||||
<label for="use-shaka"> Use Shaka Packager</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="use-ddownloader" checked /> <!-- Default checked -->
|
||||
<label for="use-ddownloader"> Use DDownloader</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="downloader-name">Executable name: </label>
|
||||
<input type="text" class="text-box" id="downloader-name" />
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<button type="button" id="export">Export Logs</button>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Keys</legend>
|
||||
<button type="button" id="clear">Clear</button>
|
||||
<div id="key-container"></div>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
||||
259
panel/panel.js
Normal file
259
panel/panel.js
Normal file
@@ -0,0 +1,259 @@
|
||||
import {
|
||||
AsyncLocalStorage,
|
||||
base64toUint8Array,
|
||||
stringToUint8Array,
|
||||
RemoteCDMManager,
|
||||
SettingsManager,
|
||||
} from "../util.js";
|
||||
|
||||
const key_container = document.getElementById("key-container");
|
||||
|
||||
// ================ Main ================
|
||||
const enabled = document.getElementById("enabled");
|
||||
enabled.addEventListener("change", async function () {
|
||||
await SettingsManager.setEnabled(enabled.checked);
|
||||
});
|
||||
|
||||
const export_button = document.getElementById("export");
|
||||
export_button.addEventListener("click", async function () {
|
||||
const logs = await AsyncLocalStorage.getStorage(null);
|
||||
SettingsManager.downloadFile(
|
||||
stringToUint8Array(JSON.stringify(logs)),
|
||||
"logs.json"
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
// ================ Remote CDM ================
|
||||
document.getElementById("remoteInput").addEventListener("click", () => {
|
||||
chrome.runtime.sendMessage({ type: "OPEN_PICKER" });
|
||||
window.close();
|
||||
});
|
||||
|
||||
const remote_remove = document.getElementById("remoteRemove");
|
||||
remote_remove.addEventListener("click", async function () {
|
||||
await RemoteCDMManager.removeSelectedRemoteCDM();
|
||||
remote_combobox.innerHTML = "";
|
||||
await RemoteCDMManager.loadSetAllRemoteCDMs();
|
||||
const selected_option =
|
||||
remote_combobox.options[remote_combobox.selectedIndex];
|
||||
if (selected_option) {
|
||||
await RemoteCDMManager.saveSelectedRemoteCDM(selected_option.text);
|
||||
} else {
|
||||
await RemoteCDMManager.removeSelectedRemoteCDMKey();
|
||||
}
|
||||
});
|
||||
|
||||
const remote_download = document.getElementById("remoteDownload");
|
||||
remote_download.addEventListener("click", async function () {
|
||||
const remote_cdm = await RemoteCDMManager.getSelectedRemoteCDM();
|
||||
SettingsManager.downloadFile(
|
||||
await RemoteCDMManager.loadRemoteCDM(remote_cdm),
|
||||
remote_cdm + ".json"
|
||||
);
|
||||
});
|
||||
|
||||
const remote_combobox = document.getElementById("remote-combobox");
|
||||
remote_combobox.addEventListener("change", async function () {
|
||||
await RemoteCDMManager.saveSelectedRemoteCDM(
|
||||
remote_combobox.options[remote_combobox.selectedIndex].text
|
||||
);
|
||||
});
|
||||
|
||||
const local_combobox = document.getElementById("local-combobox");
|
||||
local_combobox.addEventListener("change", async function () {
|
||||
await LocalCDMManager.saveSelectedLocalCDM(
|
||||
local_combobox.options[local_combobox.selectedIndex].text
|
||||
);
|
||||
});
|
||||
// ============================================
|
||||
|
||||
// ====================== Proxy Settings ======================
|
||||
|
||||
// Get elements
|
||||
const enableProxy = document.getElementById("enable-proxy");
|
||||
const proxyConfig = document.getElementById("proxy-config");
|
||||
const proxyUrlInput = document.getElementById("proxy-url");
|
||||
|
||||
// Enable or disable proxy settings
|
||||
enableProxy.addEventListener("change", async function () {
|
||||
const isProxyEnabled = enableProxy.checked;
|
||||
if (isProxyEnabled) {
|
||||
proxyConfig.style.display = "block";
|
||||
} else {
|
||||
proxyConfig.style.display = "none";
|
||||
await SettingsManager.saveProxyConfig(""); // Clear proxy setting if disabled
|
||||
}
|
||||
await SettingsManager.setProxyEnabled(isProxyEnabled);
|
||||
});
|
||||
|
||||
// Save proxy URL
|
||||
proxyUrlInput.addEventListener("input", async function () {
|
||||
const proxyUrl = proxyUrlInput.value;
|
||||
await SettingsManager.saveProxyConfig(proxyUrl); // Save the proxy config
|
||||
});
|
||||
|
||||
|
||||
// ================ Command Options ================
|
||||
const use_shaka = document.getElementById("use-shaka");
|
||||
use_shaka.addEventListener("change", async function () {
|
||||
await SettingsManager.saveUseShakaPackager(use_shaka.checked);
|
||||
});
|
||||
|
||||
const use_ddownloader = document.getElementById("use-ddownloader");
|
||||
use_shaka.addEventListener("change", async function () {
|
||||
await SettingsManager.saveUseShakaPackager(use_ddownloader.checked);
|
||||
});
|
||||
|
||||
const downloader_name = document.getElementById("downloader-name");
|
||||
downloader_name.addEventListener("input", async function (event) {
|
||||
console.log("input change", event);
|
||||
await SettingsManager.saveExecutableName(downloader_name.value);
|
||||
});
|
||||
// =================================================
|
||||
|
||||
// ================ Keys ================
|
||||
const clear = document.getElementById("clear");
|
||||
clear.addEventListener("click", async function () {
|
||||
chrome.runtime.sendMessage({ type: "CLEAR" });
|
||||
key_container.innerHTML = "";
|
||||
});
|
||||
|
||||
async function createCommand(json, key_string) {
|
||||
const metadata = JSON.parse(json);
|
||||
const header_string = Object.entries(metadata.headers)
|
||||
.map(([key, value]) => `-H "${key}: ${value.replace(/"/g, "'")}"`)
|
||||
.join(" ");
|
||||
|
||||
// Assuming `metadata.url` is the URL to use, and output is derived from `metadata.id` or some other field
|
||||
const output = metadata.id || "output"; // Change this according to how you want to generate the output name.
|
||||
|
||||
return `DDownloader -u "${metadata.url}" ${header_string} ${key_string} -o "${output}"`;
|
||||
}
|
||||
|
||||
async function appendLog(result) {
|
||||
const key_string = result.keys
|
||||
.map((key) => `--key ${key.kid}:${key.k}`)
|
||||
.join(" ");
|
||||
|
||||
const logContainer = document.createElement("div");
|
||||
logContainer.classList.add("log-container");
|
||||
logContainer.innerHTML = `
|
||||
<button class="toggleButton">+</button>
|
||||
<div class="expandableDiv collapsed">
|
||||
<label class="always-visible right-bound">
|
||||
URL:<input type="text" class="text-box" value="${result.url}">
|
||||
</label>
|
||||
<label class="expanded-only right-bound">
|
||||
<label class="expanded-only right-bound key-copy">
|
||||
<a href="#" title="Click to copy">Keys:</a><input type="text" class="text-box" value="${key_string}">
|
||||
</label>
|
||||
${
|
||||
result.manifests.length > 0
|
||||
? `<label class="expanded-only right-bound manifest-copy">
|
||||
<a href="#" title="Click to copy">Manifest:</a><select id="manifest" class="text-box"></select>
|
||||
</label>
|
||||
<label class="expanded-only right-bound command-copy">
|
||||
<a href="#" title="Click to copy">Cmd:</a><input type="text" id="command" class="text-box">
|
||||
</label>`
|
||||
: ""
|
||||
}
|
||||
</div>`;
|
||||
|
||||
const keysInput = logContainer.querySelector(".key-copy");
|
||||
keysInput.addEventListener("click", () => {
|
||||
navigator.clipboard.writeText(key_string);
|
||||
});
|
||||
|
||||
if (result.manifests.length > 0) {
|
||||
const command = logContainer.querySelector("#command");
|
||||
|
||||
const select = logContainer.querySelector("#manifest");
|
||||
select.addEventListener("change", async () => {
|
||||
command.value = await createCommand(select.value, key_string);
|
||||
});
|
||||
result.manifests.forEach((manifest) => {
|
||||
const option = new Option(
|
||||
`[${manifest.type}] ${manifest.url}`,
|
||||
JSON.stringify(manifest)
|
||||
);
|
||||
select.add(option);
|
||||
});
|
||||
command.value = await createCommand(select.value, key_string);
|
||||
|
||||
const manifest_copy = logContainer.querySelector(".manifest-copy");
|
||||
manifest_copy.addEventListener("click", () => {
|
||||
navigator.clipboard.writeText(JSON.parse(select.value).url);
|
||||
});
|
||||
|
||||
const command_copy = logContainer.querySelector(".command-copy");
|
||||
command_copy.addEventListener("click", () => {
|
||||
navigator.clipboard.writeText(command.value);
|
||||
});
|
||||
}
|
||||
|
||||
const toggleButtons = logContainer.querySelector(".toggleButton");
|
||||
toggleButtons.addEventListener("click", function () {
|
||||
const expandableDiv = this.nextElementSibling;
|
||||
if (expandableDiv.classList.contains("collapsed")) {
|
||||
toggleButtons.innerHTML = "-";
|
||||
expandableDiv.classList.remove("collapsed");
|
||||
expandableDiv.classList.add("expanded");
|
||||
} else {
|
||||
toggleButtons.innerHTML = "+";
|
||||
expandableDiv.classList.remove("expanded");
|
||||
expandableDiv.classList.add("collapsed");
|
||||
}
|
||||
});
|
||||
|
||||
key_container.appendChild(logContainer);
|
||||
}
|
||||
|
||||
chrome.storage.onChanged.addListener(async (changes, areaName) => {
|
||||
if (areaName === "local") {
|
||||
for (const [key, values] of Object.entries(changes)) {
|
||||
await appendLog(values.newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function checkLogs() {
|
||||
chrome.runtime.sendMessage({ type: "GET_LOGS" }, (response) => {
|
||||
if (response) {
|
||||
response.forEach(async (result) => {
|
||||
await appendLog(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async function () {
|
||||
enabled.checked = await SettingsManager.getEnabled();
|
||||
use_shaka.checked = await SettingsManager.getUseShakaPackager();
|
||||
downloader_name.value = await SettingsManager.getExecutableName();
|
||||
await RemoteCDMManager.loadSetAllRemoteCDMs();
|
||||
await RemoteCDMManager.selectRemoteCDM(
|
||||
await RemoteCDMManager.getSelectedRemoteCDM()
|
||||
);
|
||||
checkLogs();
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async function () {
|
||||
const isProxyEnabled = await SettingsManager.getProxyEnabled();
|
||||
enableProxy.checked = isProxyEnabled;
|
||||
if (isProxyEnabled) {
|
||||
proxyConfig.style.display = "block";
|
||||
}
|
||||
|
||||
const savedProxyUrl = await SettingsManager.getProxy();
|
||||
const savedProxyPort = await SettingsManager.getProxyPort();
|
||||
|
||||
// Combine the proxy URL and port (if available)
|
||||
if (savedProxyUrl && savedProxyPort) {
|
||||
proxyUrlInput.value = `${savedProxyUrl}:${savedProxyPort}`;
|
||||
} else {
|
||||
proxyUrlInput.value = savedProxyUrl || '';
|
||||
}
|
||||
});
|
||||
|
||||
// ======================================
|
||||
Reference in New Issue
Block a user