{"id":49013074,"url":"https://github.com/destroycom/stroygetter","last_synced_at":"2026-05-17T04:07:32.807Z","repository":{"id":193141966,"uuid":"494462702","full_name":"DestroyCom/StroyGetter","owner":"DestroyCom","description":"StroyGetter is a NextJS app which allows to download videos from YouTube.","archived":false,"fork":false,"pushed_at":"2026-05-11T15:50:36.000Z","size":55216,"stargazers_count":1,"open_issues_count":10,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-05-11T16:39:10.259Z","etag":null,"topics":["docker","ffmpeg","nextjs","nodejs","react","reactjs","youtube"],"latest_commit_sha":null,"homepage":"https://stroygetter.stroyco.eu/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DestroyCom.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":"2022-05-20T12:51:44.000Z","updated_at":"2026-05-11T15:59:52.000Z","dependencies_parsed_at":"2023-09-07T00:11:50.621Z","dependency_job_id":"75c225cb-f506-4cab-8f11-24e2f2b01fe8","html_url":"https://github.com/DestroyCom/StroyGetter","commit_stats":null,"previous_names":["destroycom/stroygetter"],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/DestroyCom/StroyGetter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DestroyCom%2FStroyGetter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DestroyCom%2FStroyGetter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DestroyCom%2FStroyGetter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DestroyCom%2FStroyGetter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DestroyCom","download_url":"https://codeload.github.com/DestroyCom/StroyGetter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DestroyCom%2FStroyGetter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32904360,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["docker","ffmpeg","nextjs","nodejs","react","reactjs","youtube"],"created_at":"2026-04-19T00:17:26.554Z","updated_at":"2026-05-11T17:03:56.616Z","avatar_url":"https://github.com/DestroyCom.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# StroyGetter\n\nAn open-source YouTube video downloader built with Next.js. Paste a URL, pick a quality, download — audio or video.\n\nLive at [stroygetter.stroyco.eu](https://stroygetter.stroyco.eu).\n\n\u003e **DISCLAIMER** — For personal and educational use only. By using this project you agree not to download content you do not hold the copyright for. Contributors cannot be held responsible for misuse or violation of any platform's terms of service.\n\n---\n\n## How it works\n\n1. User pastes a YouTube URL on the home page\n2. `youtubei.js` fetches video metadata and available formats\n3. User picks a quality (or audio-only MP3)\n4. The server downloads audio and video streams in parallel via `yt-dlp`, then merges them with FFmpeg using a lossless remux (`-c:v copy -c:a copy`)\n5. The merged file is cached in SQLite — repeat requests for the same URL + quality are served instantly from disk\n\n## Stack\n\n| Layer | Technology |\n| --- | --- |\n| Framework | Next.js 16 (App Router) |\n| Package manager | pnpm |\n| Database | SQLite via Prisma 7 |\n| Video metadata | `youtubei.js` |\n| Video download | `youtube-dl-exec` (yt-dlp) |\n| Muxing | FFmpeg |\n| Styling | Tailwind CSS + shadcn/ui |\n| Container | Docker (multi-stage, standalone output) |\n\n## Project structure\n\n```text\napp/\n  page.tsx                      # Home — URL input\n  fetch/page.tsx                # Quality picker after URL submitted\n  api/video-converter/route.ts  # GET: download, merge, stream, cache\ncomponents/custom/              # GetterInput, VideoSelect, VideoLoading\nfunctions/                      # Server actions (fetchVideoinfos, getYoutubeUrl)\nlib/\n  serverUtils.ts                # initializeConf, selectYtDlpPath, yt_validate\n  innertube.ts                  # youtubei.js singleton\n  ytdlp-info.ts                 # Format parsing\n  types.ts\nscripts/cleanup.ts              # Cron: delete expired files + DB records\nprisma/schema.prisma            # SQLite: Video → File\n```\n\n---\n\n## Local development\n\n### Requirements\n\n- Node.js 22+\n- pnpm\n- FFmpeg in PATH (or the `ffmpeg-static` fallback is used automatically)\n\n### Setup\n\n```bash\npnpm install\ncp .env.example .env          # fill in DATABASE_URL at minimum\npnpm db:deploy                # run Prisma migrations + generate client\npnpm dev                      # starts on http://localhost:3000\n```\n\n### Environment variables\n\n| Variable | Default | Description |\n| --- | --- | --- |\n| `DATABASE_URL` | — | **Required.** SQLite path, e.g. `file:./database/dev.db` |\n| `CLEANUP_INTERVAL` | `7` (prod) / `1` (dev) | Days before cached files expire |\n| `CRON` | `0 0 * * *` (prod) / `*/1 * * * *` (dev) | Cleanup cron schedule |\n| `MAX_FILESIZE` | `8G` | Max size per downloaded stream passed to yt-dlp (`--max-filesize`). Prevents disk exhaustion from oversized videos. |\n\n### With Docker (local)\n\n```bash\ndocker-compose up -d\n```\n\nApp is available on port **3002**.  \nCached downloads and the SQLite database are persisted in `./data` (mounted as `/temp/stroygetter`).\n\n\u003e **Upgrade note:** If you previously used `./docker_videos`, move or copy its contents into `./data` to keep existing cached files and database state.\n---\n\n## Releasing a new version\n\nGo to **GitHub → Actions → Release → Run workflow**, pick a bump type, and everything runs automatically.\n\n| Bump type | Example: current `3.3.0` | When to use |\n| --- | --- | --- |\n| `patch` | `3.3.0` → `3.3.1` | Bug fixes, minor tweaks |\n| `minor` | `3.3.0` → `3.4.0` | New features, backwards-compatible |\n| `major` | `3.3.0` → `4.0.0` | Breaking changes |\n\n### What happens automatically\n\n```text\nrelease.yml (workflow_dispatch: patch | minor | major)\n  └─ bump     — increments package.json, commits \"chore: release vX.Y.Z\", creates \u0026 pushes git tag\n  └─ docker   — builds Docker image, pushes destcom/stroygetter:vX.Y.Z + :latest\n  └─ github-release — creates GitHub release with auto-generated changelog (runs only if docker succeeds)\n```\n\nIf the Docker build fails, the GitHub release is not created. The `package.json` commit and git tag are still pushed — re-run the `docker` and `github-release` jobs manually from the Actions UI if needed.\n\n---\n\n## CI workflows\n\n| Workflow | Trigger | Purpose |\n| --- | --- | --- |\n| `release.yml` | Manual (Actions tab) | **Main release pipeline** — bump, tag, Docker, GitHub release |\n| `build_web_image.yml` | Called / manual | Build \u0026 push Docker image |\n| `deploy_prerelease.yml` | Called / manual | Build \u0026 push `alpha` image |\n| `create_tag.yml` | Called / manual | Create Git tag from commit message |\n| `create_release.yml` | Called / manual | Create GitHub release |\n| `deploy_version.yml` | Push to `prod` | Legacy release pipeline (push-based) |\n| `dependabot_release.yml` | Dependabot PR merged | Auto-release on `@distube/` dep update |\n| `dependabot_auto_approve.yml` | Dependabot PR opened | Auto-approve Dependabot PRs |\n\nBuilds use **Docker BuildX** with GitHub Actions cache (`type=gha`) for fast incremental rebuilds.\n\n---\n\n## Available commands\n\n```bash\npnpm dev          # Development server\npnpm build        # Production build\npnpm start        # Start production server\npnpm lint         # Biome lint\npnpm knip         # Dead code detection\npnpm db:deploy    # Run Prisma migrations + generate client\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdestroycom%2Fstroygetter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdestroycom%2Fstroygetter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdestroycom%2Fstroygetter/lists"}