Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3611d41
Add a submodule for `ejs`
tcely Nov 26, 2025
c031193
Remove `ejs` from .gitignore
tcely Nov 26, 2025
fe537a5
Update `ejs` with git in Dockerfile
tcely Nov 26, 2025
862abe7
Checkout submodules recursively
tcely Nov 26, 2025
c8609a3
Create deno.json
tcely Nov 26, 2025
b499a59
Update imports to use jsr
tcely Nov 26, 2025
61e8aa3
Remove old work-arounds
tcely Nov 26, 2025
e0b1488
Delete scripts directory
tcely Nov 26, 2025
a179f23
Update imports to use jsr in server.ts
tcely Nov 26, 2025
d7792a4
Use a later version of std/http
tcely Nov 26, 2025
cb5398f
Add imports for src/playerCache.ts
tcely Nov 26, 2025
3db5cd8
Use imports from deno.json
tcely Nov 26, 2025
19b3cb0
Create deno.lock
tcely Nov 26, 2025
0d20392
Update Dockerfile
tcely Nov 26, 2025
55c3c3b
Merge branch 'kikkia:master' into tcely-Dockerfile
tcely Nov 26, 2025
aa23c49
Handle HOME returning undefined
tcely Nov 26, 2025
23d783d
Set the owner with COPY
tcely Nov 26, 2025
0015643
Merge pull request #1 from tcely/tcely-Dockerfile
tcely Nov 26, 2025
841fc81
Re-work cache_prefix logic
tcely Nov 27, 2025
fb889f8
Switch to the debian13 image
tcely Nov 27, 2025
a21e6af
Adjust Dockerfile based on review
tcely Nov 28, 2025
f7d15ec
Merge branch 'master' into tcely-ejs
tcely Nov 30, 2025
cea36e2
update lock
PadowYT2 Dec 1, 2025
646fc4b
use esm.sh instead of a submodule for ejs
PadowYT2 Dec 1, 2025
be1525e
Merge pull request #5 from PadowYT2/tcely-ejs
tcely Dec 1, 2025
aa90b10
Clean up imports from the ejs submodule
tcely Dec 1, 2025
99b9002
Use the mapped import in server.ts
tcely Dec 1, 2025
aa11306
Update deno.lock
tcely Dec 1, 2025
39c7cca
Update README.md
tcely Dec 1, 2025
532a331
Undo workflow change for submodules
tcely Dec 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ jobs:
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
labels: ${{ steps.meta.outputs.labels }}
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
ejs/
.vscode/
.vscode/
38 changes: 18 additions & 20 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
FROM denoland/deno:latest AS builder
ARG XDG_CACHE_HOME

WORKDIR /usr/src/app

RUN apt-get update && apt-get install -y git

RUN git clone https://github.com/yt-dlp/ejs.git
# Pin to a specific commit
RUN cd ejs && git checkout 2655b1f55f98e5870d4e124704a21f4d793b4e1c && cd ..
FROM denoland/deno:debian AS builder

COPY scripts/patch-ejs.ts ./scripts/patch-ejs.ts
RUN deno run --allow-read --allow-write ./scripts/patch-ejs.ts

RUN rm -rf ./ejs/.git ./ejs/node_modules || true
WORKDIR /usr/src/app

COPY . .

RUN deno compile \
--no-check \
--output server \
--allow-net --allow-read --allow-write --allow-env \
--include worker.ts \
server.ts

RUN mkdir -p /usr/src/app/player_cache && \
chown -R deno:deno /usr/src/app/player_cache

FROM gcr.io/distroless/cc-debian12
FROM gcr.io/distroless/cc-debian13:debug
SHELL ["/busybox/busybox", "sh", "-c"]

WORKDIR /app

COPY --from=builder /tini /tini
COPY --from=builder /usr/src/app/server /app/server

COPY --from=builder --chown=nonroot:nonroot /usr/src/app/player_cache /app/player_cache
COPY --from=builder --chown=nonroot:nonroot /usr/src/app/docs /app/docs

USER nonroot
ARG XDG_CACHE_HOME
ENV XDG_CACHE_HOME="${XDG_CACHE_HOME}"
# Create the fall-back cache directories
RUN install -v -d -o nonroot -g nonroot -m 750 \
/app/player_cache /home/nonroot/.cache && \
test -z "${XDG_CACHE_HOME}" || install -v -d -m 1777 "${XDG_CACHE_HOME}"

EXPOSE 8001
ENTRYPOINT ["/app/server"]
USER nonroot
ENTRYPOINT ["/tini", "--"]
# Run the server as nonroot even when /tini runs as root
# CMD ["/busybox/busybox", "su", "-s", "/app/server", "nonroot"]
CMD ["/app/server"]
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,16 @@ docker-compose up

If you have Deno installed, you can run the service directly.

Clone the repository and patch the `ejs` dependency:
Clone the repository:

```bash
git clone https://github.com/kikkia/yt-cipher.git
cd yt-cipher
Comment thread
tcely marked this conversation as resolved.
git clone https://github.com/yt-dlp/ejs.git
cd ejs
git checkout 5d7bf090bb9a2a8f3e2dd13ded4a21a009224f87
cd ..
deno run --allow-read --allow-write ./scripts/patch-ejs.ts
```

Comment thread
tcely marked this conversation as resolved.
Run the server:

```bash
cd yt-cipher && \
deno run --allow-net --allow-read --allow-write --allow-env server.ts
```
NOTE: If using an `.env` file then also add the `--env` flag
Expand Down
12 changes: 12 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"lib": [ "deno.worker" ]
},
"imports": {
"@std/crypto": "jsr:@std/crypto@^0.224.0",
"@std/fs": "jsr:@std/fs@^0.224.0",
"@std/http": "jsr:@std/http@0.224.5",
"@std/path": "jsr:@std/path@^0.224.0",
"ejs/": "https://esm.sh/gh/yt-dlp/ejs@0.3.0&standalone/"
}
}
110 changes: 110 additions & 0 deletions deno.lock
Comment thread
tcely marked this conversation as resolved.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 0 additions & 36 deletions scripts/patch-ejs.ts

This file was deleted.

4 changes: 2 additions & 2 deletions server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { serve } from "https://deno.land/std@0.224.0/http/server.ts";
import { serve } from "@std/http";
import { initializeWorkers } from "./src/workerPool.ts";
import { initializeCache } from "./src/playerCache.ts";
import { handleDecryptSignature } from "./src/handlers/decryptSignature.ts";
Expand Down Expand Up @@ -95,4 +95,4 @@ await initializeCache();
initializeWorkers();

console.log(`Server listening on http://${host}:${port}`);
await serve(handler, { port: Number(port), hostname: host });
await serve(handler, { port: Number(port), hostname: host });
18 changes: 13 additions & 5 deletions src/playerCache.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { crypto } from "https://deno.land/std@0.224.0/crypto/mod.ts";
import { ensureDir } from "https://deno.land/std@0.224.0/fs/ensure_dir.ts";
import { join } from "https://deno.land/std@0.224.0/path/mod.ts";
import { crypto } from "@std/crypto";
import { ensureDir } from "@std/fs";
import { join } from "@std/path";
import { cacheSize, playerScriptFetches } from "./metrics.ts";

export const CACHE_HOME = Deno.env.get("XDG_CACHE_HOME") || join(Deno.env.get("HOME"), '.cache');
export const CACHE_DIR = join(CACHE_HOME, 'yt-cipher', 'player_cache');
let cache_prefix = Deno.cwd();
const HOME = Deno.env.get("HOME");
if ( HOME ) {
cache_prefix = join(HOME, '.cache', 'yt-cipher');
}
const CACHE_HOME = Deno.env.get("XDG_CACHE_HOME");
if ( CACHE_HOME ) {
cache_prefix = join(CACHE_HOME, 'yt-cipher');
}
export const CACHE_DIR = join(cache_prefix, 'player_cache');

export async function getPlayerFilePath(playerUrl: string): Promise<string> {
// This hash of the player script url will mean that diff region scripts are treated as unequals, even for the same version #
Expand Down
2 changes: 1 addition & 1 deletion src/solver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { execInPool } from "./workerPool.ts";
import { getPlayerFilePath } from "./playerCache.ts";
import { preprocessedCache } from "./preprocessedCache.ts";
import { solverCache } from "./solverCache.ts";
import { getFromPrepared } from "../ejs/src/yt/solver/solvers.ts";
import { getFromPrepared } from "ejs/src/yt/solver/solvers.ts";
import type { Solvers } from "./types.ts";
import { workerErrors } from "./metrics.ts";
import { extractPlayerId } from "./utils.ts";
Expand Down
2 changes: 0 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { Input as MainInput, Output as MainOutput } from "../ejs/src/yt/solver/main.ts";

export interface Solvers {
n: ((val: string) => string) | null;
sig: ((val: string) => string) | null;
Expand Down
2 changes: 1 addition & 1 deletion worker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { preprocessPlayer } from "./ejs/src/yt/solver/solvers.ts";
import { preprocessPlayer } from "ejs/src/yt/solver/solvers.ts";

self.onmessage = (e: MessageEvent<string>) => {
try {
Expand Down