From dcb7cfec276d93eeb139a15c140c8f59e99ff9cd Mon Sep 17 00:00:00 2001
From: 0d0 <0d0acre@esiliati.org>
Date: Sun, 23 Feb 2025 04:55:09 +0100
Subject: [PATCH] Add loader and new formats
---
src/lib/common/supportedFormats.json | 6 ++
src/lib/components/Loader.svelte | 6 +-
src/lib/server/helpers.ts | 14 ++++
src/lib/server/ytdlp.ts | 23 ++++--
src/routes/+page.svelte | 112 +++++++++++++++++++++------
src/routes/download/+server.ts | 27 ++++---
6 files changed, 148 insertions(+), 40 deletions(-)
create mode 100644 src/lib/common/supportedFormats.json
create mode 100644 src/lib/server/helpers.ts
diff --git a/src/lib/common/supportedFormats.json b/src/lib/common/supportedFormats.json
new file mode 100644
index 0000000..80187b0
--- /dev/null
+++ b/src/lib/common/supportedFormats.json
@@ -0,0 +1,6 @@
+{
+ "mp3": "audio/mpeg",
+ "mp4": "video/mp4",
+ "opus": "audio/ogg",
+ "wav": "audio/wav"
+}
\ No newline at end of file
diff --git a/src/lib/components/Loader.svelte b/src/lib/components/Loader.svelte
index 62b43fc..df33172 100644
--- a/src/lib/components/Loader.svelte
+++ b/src/lib/components/Loader.svelte
@@ -1,6 +1,8 @@
diff --git a/src/lib/server/helpers.ts b/src/lib/server/helpers.ts
new file mode 100644
index 0000000..af5111d
--- /dev/null
+++ b/src/lib/server/helpers.ts
@@ -0,0 +1,14 @@
+import formats from '$lib/common/supportedFormats.json';
+
+const formatMime = new Map(Object.entries(formats))
+
+export const mimeTypeMap = formatMime;
+export const contentTypeFromFormat = (format: string): string => {
+ const toReturn: string | undefined = formatMime.get(format)
+
+ if (!toReturn) {
+ throw new Error("Unsupported format")
+ }
+
+ return toReturn;
+}
\ No newline at end of file
diff --git a/src/lib/server/ytdlp.ts b/src/lib/server/ytdlp.ts
index f37ddef..9afded2 100644
--- a/src/lib/server/ytdlp.ts
+++ b/src/lib/server/ytdlp.ts
@@ -1,6 +1,9 @@
import { create } from 'youtube-dl-exec';
import { env } from '$env/dynamic/private';
import { spawn } from 'node:child_process';
+import supportedFormats from '$lib/common/supportedFormats.json';
+import { mimeTypeMap } from '$lib/server/helpers';
+
const YTDLP_PATH: string = env.YTDLP_PATH as string;
export const ytdl = create(YTDLP_PATH);
@@ -21,19 +24,27 @@ export async function getYouTubeMetadata(link: string) {
* Streams the YouTube video/audio using youtube-dl-exec
*/
export function streamYouTube(link: string, format: string): ReadableStream {
+ const mimeType: string | undefined = mimeTypeMap.get(format)
+
+ if (!mimeType) {
+ throw new Error("Unsupported format");
+ }
+
return new ReadableStream({
start(controller) {
const args = [
'-o',
'-',
- format === 'mp3' ? '--embed-metadata' : '',
- '--format',
- format === 'mp3' ? 'bestaudio' : 'best',
- '--audio-format',
- format === 'mp3' ? 'mp3' : '',
- '--no-playlist'
].filter(Boolean);
+ if(mimeType?.includes('audio')) {
+ args.push(...['--extract-audio', '--embed-metadata', '--embed-thumbnail', '--audio-format', format])
+ } else if (mimeType.includes('video')) {
+ args.push(...['--embed-metadata', '--embed-thumbnail', '--format', format])
+ }
+
+ console.info(`yt-dlp ${args.join(' ')} ${link}`)
+
const process = spawn('yt-dlp', [...args, link], { stdio: ['ignore', 'pipe', 'ignore'] });
process.stdout.on('data', (chunk) => controller.enqueue(chunk));
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 098ef91..0e2f7e8 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,35 +1,80 @@