mirror of
https://github.com/yt-dlp/ejs.git
synced 2026-06-16 18:22:15 +00:00
Adjust for yt-dlp changes
This commit is contained in:
@@ -3,9 +3,9 @@ requires = ["hatchling", "hatch-build-scripts"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "yt-dlp-jsc-deno"
|
||||
name = "yt-dlp-jsc"
|
||||
version = "0.0.1"
|
||||
description = "JavaScript Challenge Provider for yt-dlp using Deno"
|
||||
description = "JavaScript Challenge Provider for yt-dlp supporting many runtimes"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
license = "Unlicense"
|
||||
@@ -16,7 +16,6 @@ authors = [
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
@@ -29,16 +28,18 @@ classifiers = [
|
||||
dependencies = []
|
||||
|
||||
[project.urls]
|
||||
Documentation = "https://github.com/yt-dlp/yt-dlp-jsc-deno#readme"
|
||||
Issues = "https://github.com/yt-dlp/yt-dlp-jsc-deno/issues"
|
||||
Source = "https://github.com/yt-dlp/yt-dlp-jsc-deno"
|
||||
Documentation = "https://github.com/yt-dlp/yt-dlp-jsc#readme"
|
||||
Issues = "https://github.com/yt-dlp/yt-dlp-jsc/issues"
|
||||
Source = "https://github.com/yt-dlp/yt-dlp-jsc"
|
||||
|
||||
[[tool.hatch.build.hooks.build-scripts.scripts]]
|
||||
work_dir = "dist"
|
||||
out_dir = "yt_dlp_jsc_deno"
|
||||
out_dir = "yt_dlp_jsc"
|
||||
commands = [
|
||||
"deno install",
|
||||
"deno task bundle",
|
||||
]
|
||||
artifacts = [
|
||||
"jsc-deno.js",
|
||||
"jsc.min.js",
|
||||
"lib.min.js",
|
||||
]
|
||||
|
||||
38
src/main.ts
38
src/main.ts
@@ -8,32 +8,30 @@ export default function main(input: Input): Output {
|
||||
const solvers = getFromPrepared(preprocessedPlayer);
|
||||
|
||||
const responses = input.requests.map(
|
||||
(request): JsChallengeProviderResponse => {
|
||||
if (!isOneOf(request.type, "nsig", "sig")) {
|
||||
(input): Response => {
|
||||
if (!isOneOf(input.type, "nsig", "sig")) {
|
||||
return {
|
||||
type: "error",
|
||||
request,
|
||||
error: `Unknown request type: ${request.type}`,
|
||||
error: `Unknown request type: ${input.type}`,
|
||||
};
|
||||
}
|
||||
const solver = solvers[request.type];
|
||||
const solver = solvers[input.type];
|
||||
if (!solver) {
|
||||
return {
|
||||
type: "error",
|
||||
request,
|
||||
error: `Failed to extract ${request.type} function`,
|
||||
error: `Failed to extract ${input.type} function`,
|
||||
};
|
||||
}
|
||||
try {
|
||||
return {
|
||||
type: "result",
|
||||
request,
|
||||
response: solver(request.challenge),
|
||||
data: Object.fromEntries(
|
||||
input.challenges.map((challenge) => [challenge, solver(challenge)]),
|
||||
),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
type: "error",
|
||||
request,
|
||||
error: error instanceof Error
|
||||
? `${error.message}\n${error.stack}`
|
||||
: `${error}`,
|
||||
@@ -56,31 +54,27 @@ export type Input =
|
||||
| {
|
||||
type: "player";
|
||||
player: string;
|
||||
requests: JsChallengeRequest[];
|
||||
requests: Request[];
|
||||
output_preprocessed: boolean;
|
||||
}
|
||||
| {
|
||||
type: "preprocessed";
|
||||
preprocessed_player: string;
|
||||
requests: JsChallengeRequest[];
|
||||
requests: Request[];
|
||||
};
|
||||
|
||||
type JsChallengeRequest = {
|
||||
type: string;
|
||||
challenge: string;
|
||||
player_url: string;
|
||||
video_id: string | null;
|
||||
type Request = {
|
||||
type: "nsig" | "sig";
|
||||
challenges: string[];
|
||||
};
|
||||
|
||||
type JsChallengeProviderResponse =
|
||||
type Response =
|
||||
| {
|
||||
type: "result";
|
||||
request: JsChallengeRequest;
|
||||
response: string;
|
||||
data: Record<string, string>;
|
||||
}
|
||||
| {
|
||||
type: "error";
|
||||
request: JsChallengeRequest;
|
||||
error: string;
|
||||
};
|
||||
|
||||
@@ -88,7 +82,7 @@ export type Output =
|
||||
| {
|
||||
type: "result";
|
||||
preprocessed_player?: string;
|
||||
responses: JsChallengeProviderResponse[];
|
||||
responses: Response[];
|
||||
}
|
||||
| {
|
||||
type: "error";
|
||||
|
||||
10
tests/io.ts
10
tests/io.ts
@@ -25,14 +25,19 @@ export async function getIO(): Promise<IO> {
|
||||
async function _getIO(): Promise<IO> {
|
||||
if (globalThis.process?.release?.name === "node") {
|
||||
// Assume node compatibility
|
||||
const { readFile, writeFile, access } = await import("node:fs/promises");
|
||||
const { access, readFile } = await import("node:fs/promises");
|
||||
const { deepStrictEqual } = await import("node:assert");
|
||||
const assert: Assert = {
|
||||
equal: deepStrictEqual,
|
||||
};
|
||||
let test: Test;
|
||||
let writeFile: (
|
||||
file: string,
|
||||
data: ReadableStream<Uint8Array>,
|
||||
) => Promise<void>;
|
||||
if (typeof globalThis.Deno !== "undefined") {
|
||||
// deno does not like `node:test` for some reason
|
||||
// Except for Deno, which does its own thing
|
||||
writeFile = Deno.writeFile;
|
||||
test = (name, func) => {
|
||||
Deno.test(name, (t) => {
|
||||
return func(assert, async (name, func): Promise<void> => {
|
||||
@@ -44,6 +49,7 @@ async function _getIO(): Promise<IO> {
|
||||
return Promise.resolve();
|
||||
};
|
||||
} else {
|
||||
writeFile = (await import("node:fs/promises"))["writeFile"];
|
||||
const { suite, test: subtest } = await import("node:test");
|
||||
test = (name, func) => {
|
||||
suite(name, () => {
|
||||
|
||||
120
tests/tests.ts
120
tests/tests.ts
@@ -83,6 +83,126 @@ export const tests: {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "3752a005",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
nsig: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "afc7785b",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
nsig: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "b9645327",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
nsig: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "035b9195",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
nsig: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "6740c111",
|
||||
nsig: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "AVsXYE0uE1k8e" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"JfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYu7S6SHM8EjoCACIEQnz-MKN5RgG6iUTnNJC58csYPSrnS_SzricuUMJZGn",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "f6a4f3bc",
|
||||
nsig: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "H1NKYFbhlqZ" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"JfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYM7S6SHM8EjoCACIEQnz-nKM5RgG6iUTnNJC58cNYPSrnS_SzricuUMJZGu",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "b66835e2",
|
||||
nsig: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "H1NKYFbhlqZ" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"JfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYM7S6SHM8EjoCACIEQnz-nKM5RgG6iUTnNJC58cNYPSrnS_SzricuUMJZGu",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const players = new Map(
|
||||
|
||||
26
yt_dlp_jsc/__init__.py
Normal file
26
yt_dlp_jsc/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import importlib.resources
|
||||
import importlib.metadata
|
||||
|
||||
import yt_dlp_jsc
|
||||
|
||||
version = importlib.metadata.version(yt_dlp_jsc.__name__)
|
||||
|
||||
|
||||
def jsc() -> str:
|
||||
"""
|
||||
Read the contents of the JavaScript jsc bundle as string.
|
||||
"""
|
||||
return importlib.resources.read_text(yt_dlp_jsc, 'jsc.min.js')
|
||||
|
||||
|
||||
def lib() -> str:
|
||||
"""
|
||||
Read the contents of the JavaScript library bundle as string.
|
||||
"""
|
||||
return importlib.resources.read_text(yt_dlp_jsc, 'lib.min.js')
|
||||
|
||||
__all__ = [
|
||||
"jsc",
|
||||
"lib",
|
||||
"version",
|
||||
]
|
||||
1
yt_dlp_jsc/jsc.min.js
vendored
Normal file
1
yt_dlp_jsc/jsc.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
yt_dlp_jsc/lib.min.js
vendored
Normal file
1
yt_dlp_jsc/lib.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,20 +0,0 @@
|
||||
import importlib.resources
|
||||
import importlib.metadata
|
||||
|
||||
import yt_dlp_jsc_deno
|
||||
|
||||
_name = "jsc-deno.js"
|
||||
|
||||
version = importlib.metadata.version(yt_dlp_jsc_deno.__name__)
|
||||
|
||||
|
||||
def exists() -> bool:
|
||||
return importlib.resources.is_resource(yt_dlp_jsc_deno, _name)
|
||||
|
||||
|
||||
def read() -> str:
|
||||
return importlib.resources.read_text(yt_dlp_jsc_deno, _name)
|
||||
|
||||
|
||||
def path():
|
||||
return importlib.resources.path(yt_dlp_jsc_deno, _name)
|
||||
Reference in New Issue
Block a user