diff --git a/package-lock.json b/package-lock.json index f07e6551..de279251 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@radix-ui/react-label": "^2.0.1", "@radix-ui/react-popover": "^1.0.6", "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-select": "^1.2.2", "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tabs": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.5", @@ -48,6 +49,7 @@ "clsx": "^1.2.1", "cookie": "^0.5.0", "file-saver": "^2.0.5", + "fluent-ffmpeg": "^2.1.2", "framer-motion": "^10.6.0", "fs": "^0.0.1-security", "fuse.js": "^6.6.2", @@ -94,6 +96,7 @@ "tailwindcss-animate": "^1.0.5", "twin.macro": "^3.1.0", "usehooks-ts": "^2.9.1", + "ytdl-core": "^4.11.5", "zod": "^3.20.6" }, "devDependencies": { @@ -1325,6 +1328,14 @@ "node": ">=16.3.0" } }, + "node_modules/@radix-ui/number": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", + "integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, "node_modules/@radix-ui/primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", @@ -1959,6 +1970,49 @@ } } }, + "node_modules/@radix-ui/react-select": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-1.2.2.tgz", + "integrity": "sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.1", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.3", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.2", + "@radix-ui/react-portal": "1.0.3", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", @@ -3363,6 +3417,11 @@ "dev": true, "license": "ISC" }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5353,6 +5412,29 @@ "dev": true, "license": "ISC" }, + "node_modules/fluent-ffmpeg": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", + "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==", + "dependencies": { + "async": ">=0.2.9", + "which": "^1.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fluent-ffmpeg/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -6469,7 +6551,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/isomorphic-fetch": { @@ -6768,6 +6849,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/marked": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz", @@ -6870,6 +6963,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", @@ -8798,6 +8899,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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", @@ -10263,6 +10369,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.4", "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", @@ -11073,6 +11192,14 @@ "yargs": "17.7.1" } }, + "@radix-ui/number": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", + "integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, "@radix-ui/primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", @@ -11389,6 +11516,35 @@ "@radix-ui/react-use-controllable-state": "1.0.1" } }, + "@radix-ui/react-select": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-1.2.2.tgz", + "integrity": "sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.1", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.3", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-popper": "1.1.2", + "@radix-ui/react-portal": "1.0.3", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + } + }, "@radix-ui/react-slot": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", @@ -12324,6 +12480,11 @@ "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -13666,6 +13827,25 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "fluent-ffmpeg": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", + "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==", + "requires": { + "async": ">=0.2.9", + "which": "^1.1.1" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -14364,8 +14544,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isomorphic-fetch": { "version": "3.0.0", @@ -14582,6 +14761,15 @@ "dev": true, "requires": {} }, + "m3u8stream": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.6.tgz", + "integrity": "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==", + "requires": { + "miniget": "^4.2.2", + "sax": "^1.2.4" + } + }, "marked": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz", @@ -14643,6 +14831,11 @@ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" }, + "miniget": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/miniget/-/miniget-4.2.3.tgz", + "integrity": "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -15759,6 +15952,11 @@ "is-regex": "^1.1.4" } }, + "sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, "scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -16762,6 +16960,16 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true }, + "ytdl-core": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz", + "integrity": "sha512-27LwsW4n4nyNviRCO1hmr8Wr5J1wLLMawHCQvH8Fk0hiRqrxuIu028WzbJetiYH28K8XDbeinYW4/wcHQD1EXA==", + "requires": { + "m3u8stream": "^0.8.6", + "miniget": "^4.2.2", + "sax": "^1.1.3" + } + }, "zod": { "version": "3.21.4", "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", diff --git a/package.json b/package.json index fea15122..eb25af97 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "clsx": "^1.2.1", "cookie": "^0.5.0", "file-saver": "^2.0.5", + "fluent-ffmpeg": "^2.1.2", "framer-motion": "^10.6.0", "fs": "^0.0.1-security", "fuse.js": "^6.6.2", @@ -96,6 +97,7 @@ "tailwindcss-animate": "^1.0.5", "twin.macro": "^3.1.0", "usehooks-ts": "^2.9.1", + "ytdl-core": "^4.11.5", "zod": "^3.20.6" }, "devDependencies": { diff --git a/src/components/EmbedVideoSettings/index.tsx b/src/components/EmbedVideoSettings/index.tsx index 974495b2..0ab4e5ed 100644 --- a/src/components/EmbedVideoSettings/index.tsx +++ b/src/components/EmbedVideoSettings/index.tsx @@ -22,6 +22,13 @@ import { debounce } from "lodash"; import { ReactEditor } from "slate-react"; import { Element as SlateElement, Node, Transforms } from "slate"; import { Input } from "../ui/input"; +import { api } from "@/utils/api"; + +type DownloadVideoResponse = { + success: boolean; + videoId?: string; + error?: string; +}; export const EmbedVideoSettings = ({ element }) => { const { editor, activePath } = useContext(EditorContext); @@ -109,10 +116,24 @@ export const EmbedVideoSettings = ({ element }) => { setEmbedLink(e.target.value); }; + const downloadVideoMutation = api.workspace.downloadVideo.useMutation(); + + const downloadVideoHandler = async () => { + try { + const response = await downloadVideoMutation.mutateAsync({ + link: element.actualLink, + }); + if (response && response.success) { + console.log(response.success); + } + } catch (error) { + console.error("Error:", error); + } + }; + return (

Embed Video Settings

-
{
+ + ); }; diff --git a/src/server/api/routers/workspace.ts b/src/server/api/routers/workspace.ts index 36d6184b..51c8b16b 100644 --- a/src/server/api/routers/workspace.ts +++ b/src/server/api/routers/workspace.ts @@ -13,8 +13,18 @@ import { Redis } from "@upstash/redis"; import { TRPCError } from "@trpc/server"; import puppeteer from "puppeteer"; +import ytdl from "ytdl-core"; +import { v4 as uuidv4 } from "uuid"; +import { createWriteStream } from "fs"; +import { join } from "path"; +import ffmpeg from "fluent-ffmpeg"; +import { pipeline } from "stream"; +import { promisify } from "util"; + const ee = new EventEmitter(); +const asyncPipeline = promisify(pipeline); + export const workspaceRouter = createTRPCRouter({ changeFont: protectedProcedure .input(z.object({ id: z.string(), font: z.string() })) @@ -414,4 +424,36 @@ export const workspaceRouter = createTRPCRouter({ return { pdf: pdfBase64 }; }), + downloadVideo: protectedProcedure + .input(z.object({ link: z.string() })) + .mutation(async ({ input, ctx }) => { + try { + const videoStream = ytdl(input.link, { quality: "highestvideo" }); + const audioStream = ytdl(input.link, { quality: "highestaudio" }); + + const videoWriteStream = createWriteStream("video.mp4"); + const audioWriteStream = createWriteStream("audio.mp4"); + + // Saving video and audio to disk + await Promise.all([ + asyncPipeline(videoStream, videoWriteStream), + asyncPipeline(audioStream, audioWriteStream), + ]); + + // Combining video and audio with ffmpeg + await new Promise((resolve, reject) => { + ffmpeg() + .input("video.mp4") + .input("audio.mp4") + .on("end", resolve) + .on("error", reject) + .mergeToFile("finalOutput.mp4"); + }); + + return { success: true }; + } catch (error) { + console.error("Error:", error); + return { success: false, error: error.message }; + } + }), }); diff --git a/yarn.lock b/yarn.lock index c59156a2..69d2bcac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -625,6 +625,13 @@ "unbzip2-stream" "1.4.3" "yargs" "17.7.1" +"@radix-ui/number@1.0.1": + "integrity" "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==" + "resolved" "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive@1.0.1": "integrity" "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==" "resolved" "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz" @@ -917,6 +924,34 @@ "@radix-ui/react-use-callback-ref" "1.0.1" "@radix-ui/react-use-controllable-state" "1.0.1" +"@radix-ui/react-select@^1.2.2": + "integrity" "sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==" + "resolved" "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-1.2.2.tgz" + "version" "1.2.2" + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/number" "1.0.1" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.4" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.3" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.2" + "@radix-ui/react-portal" "1.0.3" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-use-previous" "1.0.1" + "@radix-ui/react-visually-hidden" "1.0.3" + "aria-hidden" "^1.1.1" + "react-remove-scroll" "2.5.5" + "@radix-ui/react-slot@1.0.2": "integrity" "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==" "resolved" "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz" @@ -1678,6 +1713,11 @@ dependencies: "tslib" "^2.0.1" +"async@>=0.2.9": + "integrity" "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + "resolved" "https://registry.npmjs.org/async/-/async-3.2.4.tgz" + "version" "3.2.4" + "asynckit@^0.4.0": "integrity" "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" @@ -2858,6 +2898,14 @@ "resolved" "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" "version" "3.2.7" +"fluent-ffmpeg@^2.1.2": + "integrity" "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==" + "resolved" "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz" + "version" "2.1.2" + dependencies: + "async" ">=0.2.9" + "which" "^1.1.1" + "follow-redirects@^1.14.8", "follow-redirects@^1.15.0": "integrity" "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" @@ -3734,6 +3782,14 @@ "resolved" "https://registry.npmjs.org/lucide-react/-/lucide-react-0.268.0.tgz" "version" "0.268.0" +"m3u8stream@^0.8.6": + "integrity" "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==" + "resolved" "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.6.tgz" + "version" "0.8.6" + dependencies: + "miniget" "^4.2.2" + "sax" "^1.2.4" + "marked@^5.1.2": "integrity" "sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==" "resolved" "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz" @@ -3800,6 +3856,11 @@ "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" "version" "3.1.0" +"miniget@^4.2.2": + "integrity" "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==" + "resolved" "https://registry.npmjs.org/miniget/-/miniget-4.2.3.tgz" + "version" "4.2.3" + "minimatch@^3.0.4", "minimatch@^3.0.5", "minimatch@^3.1.1", "minimatch@^3.1.2": "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -4709,6 +4770,11 @@ "get-intrinsic" "^1.1.3" "is-regex" "^1.1.4" +"sax@^1.1.3", "sax@^1.2.4": + "integrity" "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + "resolved" "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz" + "version" "1.3.0" + "scheduler@^0.23.0": "integrity" "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==" "resolved" "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" @@ -5462,6 +5528,13 @@ "has-tostringtag" "^1.0.0" "is-typed-array" "^1.1.10" +"which@^1.1.1": + "integrity" "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==" + "resolved" "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + "version" "1.3.1" + dependencies: + "isexe" "^2.0.0" + "which@^2.0.1": "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -5572,6 +5645,15 @@ "resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" "version" "0.1.0" +"ytdl-core@^4.11.5": + "integrity" "sha512-27LwsW4n4nyNviRCO1hmr8Wr5J1wLLMawHCQvH8Fk0hiRqrxuIu028WzbJetiYH28K8XDbeinYW4/wcHQD1EXA==" + "resolved" "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz" + "version" "4.11.5" + dependencies: + "m3u8stream" "^0.8.6" + "miniget" "^4.2.2" + "sax" "^1.1.3" + "zod@^3.20.6", "zod@3.21.4": "integrity" "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==" "resolved" "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz"