From 258e884cc56b440982493859aa4fda8a2b77dc00 Mon Sep 17 00:00:00 2001 From: Christian Brown Date: Sat, 13 Jan 2024 23:56:58 -0600 Subject: [PATCH] test --- .gitignore | 3 +++ package-lock.json | 41 +++++++++++++++++++++++++++++++- package.json | 5 ++-- public/downloads/.gitkeep | 0 src/pages/ytdl.ts | 49 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 public/downloads/.gitkeep create mode 100644 src/pages/ytdl.ts diff --git a/.gitignore b/.gitignore index eb459b3..9fbca8f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,5 +23,8 @@ pnpm-debug.log* # might have an old src for reference src-old/ +/public/downloads/* +!/public/downloads/.gitkeep + # lighthouse .lighthouseci/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c022c60..09ca18a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,8 @@ "react-dom": "^18.2.0", "tailwind-merge": "^1.14.0", "tailwindcss": "^3.3.3", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "ytdl-core": "^4.11.5" }, "devDependencies": { "@lhci/cli": "^0.13.0", @@ -5725,6 +5726,18 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } }, + "node_modules/m3u8stream": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.6.tgz", + "integrity": "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==", + "dependencies": { + "miniget": "^4.2.2", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/magic-string": { "version": "0.30.3", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", @@ -6639,6 +6652,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/miniget": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/miniget/-/miniget-4.2.3.tgz", + "integrity": "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==", + "engines": { + "node": ">=12" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -8493,6 +8514,11 @@ "suf-log": "^2.5.3" } }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -10655,6 +10681,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ytdl-core": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz", + "integrity": "sha512-27LwsW4n4nyNviRCO1hmr8Wr5J1wLLMawHCQvH8Fk0hiRqrxuIu028WzbJetiYH28K8XDbeinYW4/wcHQD1EXA==", + "dependencies": { + "m3u8stream": "^0.8.6", + "miniget": "^4.2.2", + "sax": "^1.1.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/zod": { "version": "3.21.1", "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.1.tgz", diff --git a/package.json b/package.json index d1e498f..931a821 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "react-dom": "^18.2.0", "tailwind-merge": "^1.14.0", "tailwindcss": "^3.3.3", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "ytdl-core": "^4.11.5" }, "devDependencies": { "@lhci/cli": "^0.13.0", @@ -64,4 +65,4 @@ "prettier-plugin-tailwindcss" ] } -} \ No newline at end of file +} diff --git a/public/downloads/.gitkeep b/public/downloads/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/ytdl.ts b/src/pages/ytdl.ts new file mode 100644 index 0000000..c2eaf08 --- /dev/null +++ b/src/pages/ytdl.ts @@ -0,0 +1,49 @@ +import type { APIRoute } from 'astro' +import fs from 'fs' +import ytdl from 'ytdl-core' +import crypto from 'crypto' + +const sleep = (ms: number) => { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, ms) + }) +} + +export const GET: APIRoute = async () => { + const url = 'https://www.youtube.com/watch?v=a5ITNmnS680' + const id = crypto.randomUUID() + const filename = `${id}.mp4` + const target = `./public/downloads/${filename}` + + let isRunning = true + + console.log('downloading %s', url) + ytdl(url) + .pipe(fs.createWriteStream(target)) + .on('finish', () => { + console.log('Download completed!') + isRunning = false + }) + + while (isRunning) { + console.log('still downloading...') + await sleep(5000) + } + + console.log('download complete!') + + return new Response( + JSON.stringify({ + message: 'your file is ready', + time: new Date(), + }), + { + status: 200, + headers: { + 'Content-Disposition': `attachment; filename="${target}"`, + }, + }, + ) +}