{"id":49245048,"url":"https://github.com/itz4blitz/jellytube","last_synced_at":"2026-04-24T21:05:24.546Z","repository":{"id":349415323,"uuid":"1202217285","full_name":"itz4blitz/Jellytube","owner":"itz4blitz","description":"Jellyfin-backed request layer for web video downloads","archived":false,"fork":false,"pushed_at":"2026-04-05T19:55:15.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-05T21:28:43.531Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itz4blitz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-05T18:50:37.000Z","updated_at":"2026-04-05T19:55:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/itz4blitz/Jellytube","commit_stats":null,"previous_names":["itz4blitz/jellytube"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/itz4blitz/Jellytube","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itz4blitz%2FJellytube","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itz4blitz%2FJellytube/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itz4blitz%2FJellytube/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itz4blitz%2FJellytube/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itz4blitz","download_url":"https://codeload.github.com/itz4blitz/Jellytube/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itz4blitz%2FJellytube/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32240620,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-24T21:05:09.400Z","updated_at":"2026-04-24T21:05:24.525Z","avatar_url":"https://github.com/itz4blitz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jellytube\n\n`Jellytube` is a Jellyfin-backed request layer for web video downloads.\n\nIt is built for the setup where:\n\n- `Jellyfin` already owns the users and passwords\n- `MeTube` is the private download worker for `yt-dlp`\n- users should be attributable back to Jellyfin identities\n- admins need approval, audit, and queue visibility before content lands in the library\n\n## What The MVP Does\n\n- authenticates users directly against Jellyfin\n- accepts signed Jellyfin bridge handoff tokens from a Jellyfin plugin\n- stores a signed Jellytube session cookie after successful Jellyfin login\n- records requests with Jellyfin user id, username, source, kind, and timestamps\n- supports admin approval and rejection for requests\n- can queue approved requests into MeTube through `POST /add`\n- ships with a tiny Chrome extension that can target either Jellytube directly or the Jellyfin bridge launch URL\n\n## Why It Exists\n\n`MeTube` is a strong downloader, but it does not give you a real user/request model that maps back to Jellyfin.\n\nJellytube keeps the responsibilities separated:\n\n- `Jellyfin`: identity and admin role\n- `Jellytube`: request tracking, approval flow, audit trail, MeTube orchestration\n- `MeTube`: private download worker\n\n## Repo Layout\n\n- `apps/server`: Fastify service, auth flow, request API, built-in browser UI\n- `plugins/Jellytube.JellyfinBridge`: Jellyfin plugin for signed handoff into Jellytube from Jellyfin Web\n- `extensions/chrome`: small browser extension that opens a configured launch URL with the current page prefilled\n- `docs/architecture.md`: system design notes and next-step boundaries\n\n## Current Scope\n\nThis repo intentionally does not try to make MeTube itself multi-user.\n\nInstead it provides:\n\n- a user-facing request layer\n- admin controls around approval and audit\n- a Jellyfin Web bridge so users can start from inside Jellyfin\n\n## Local Development\n\n1. Copy `.env.example` to `.env`\n2. Set `JELLYFIN_URL`, `METUBE_URL`, `COOKIE_SECRET`, and `HANDOFF_SECRET`\n3. Install dependencies and start the service\n\n```bash\npnpm install\ncp .env.example .env\npnpm dev:server\n```\n\nThe app will be available at `http://localhost:3135` by default.\n\n## Build And Test\n\n```bash\npnpm build\npnpm test\npnpm typecheck\n```\n\nThe root build compiles both:\n\n- the Jellytube server\n- the Jellytube Jellyfin bridge plugin\n\n## Docker Image\n\nGitHub Actions publishes the server image to GHCR on pushes to `main`.\n\n```text\nghcr.io/itz4blitz/jellytube:latest\n```\n\nUseful tags:\n\n- `latest`: current `main`\n- `main`: latest branch build for `main`\n- `sha-\u003ccommit\u003e`: exact immutable build for a specific commit\n\nExample:\n\n```bash\ndocker pull ghcr.io/itz4blitz/jellytube:latest\n```\n\nThe container serves the Jellytube web UI and API. The Jellyfin bridge plugin is still a separate build artifact from `plugins/Jellytube.JellyfinBridge`.\n\n## Chrome Extension\n\nThe extension is intentionally small.\n\nIt lets a user:\n\n- configure a launch URL\n- configure the display label for the site name\n- open the configured launch URL with the current tab URL prefilled\n- use context-menu entries for page URLs or links\n\nRecommended launch URL once the plugin is installed:\n\n```text\nhttps://your-jellyfin.example.com/JellytubeBridge/start\n```\n\nThat keeps the user flow Jellyfin-first while still landing them in Jellytube with a signed handoff.\n\nLoad it in Chrome via `chrome://extensions` using \"Load unpacked\" and select `extensions/chrome`.\n\n## Environment\n\n- `JELLYFIN_URL`: Jellyfin base URL used for direct auth\n- `METUBE_URL`: internal MeTube URL, for example `http://metube:8081`\n- `COOKIE_SECRET`: long random secret for signing Jellytube session cookies\n- `HANDOFF_SECRET`: long random secret shared with the Jellytube Jellyfin bridge plugin\n- `AUTO_APPROVE_VIDEO_REQUESTS`: if `true`, direct video requests are immediately queued to MeTube\n- `ALLOWED_HOSTS`: comma-separated allowlist for non-admin submissions\n\n## Jellyfin Web Flow\n\nThe intended browser flow is:\n\n1. User is already signed in to Jellyfin Web\n2. User opens `/JellytubeBridge/start`\n3. The plugin helper page reuses the current Jellyfin session\n4. The plugin issues a short-lived signed handoff token\n5. Jellytube verifies the token and creates its own session cookie\n6. The request UI opens with the user already authenticated\n\nThis is the supported \"inside Jellyfin Web\" story.\n\nNative TV and mobile clients still benefit after download because playback happens through the normal Jellyfin library once the files exist.\n\n## Recommended Production Shape\n\n- keep MeTube private\n- expose Jellytube instead of MeTube\n- put Cloudflare Access or another front-door control in front of Jellytube if needed\n- use the Jellytube Jellyfin bridge for first-class in-Jellyfin browser launch\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitz4blitz%2Fjellytube","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitz4blitz%2Fjellytube","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitz4blitz%2Fjellytube/lists"}