import { error } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; import { getYouTubeMetadata, streamYouTube, ytdl } from '$lib/server/ytdlp'; import { isURLValid, logger, mimeTypeMap } from '$lib/server/helpers'; const validateRequest = (url: URL) => { // Get query params const link = url.searchParams.get('link'); const format = url.searchParams.get('format'); // mp3, mp4 const source = url.searchParams.get('source'); // youtube or spotify const metadata = url.searchParams.has('metadata'); // Validate input if (!link || !format || !source) { throw error(400, 'Missing required query parameters: link, format, or source'); } if (source !== 'youtube') { throw error(400, 'Currently, only YouTube is supported'); } if (!isURLValid(link)) { throw error(400, 'URL not valid'); } if (!mimeTypeMap.get(format)) { throw error(400, 'format not valid'); } logger.debug(`Request is valid`); return { link, format, source, metadata }; }; export const GET: RequestHandler = async ({ url }) => { const { format, source, metadata, link } = validateRequest(url); let filename = `you-clicked-no-metadata-so-i-cant-put-a-correct-name.${format}`; if (!!metadata) { try { logger.debug(`Fetching video data to set filename`); // Fetch metadata for filename const ytMetadata = await getYouTubeMetadata(link); const { title, uploader } = ytMetadata; const safeTitle = `${uploader} - ${title}`; filename = `${safeTitle}.${format}`; } catch (err) { logger.error(err); logger.error('Error fetching metadata:'); throw error(500, 'Failed to fetch video metadata'); } } try { // Stream video/audio return new Response(streamYouTube(link, format), { headers: { 'Content-Type': `${mimeTypeMap.get(format)}`, 'Content-Disposition': `attachment; filename="${filename}"`, 'Set-Cookie': 'downloading=0' } }); } catch (err) { logger.error(err); logger.error('Filed to stream file'); throw error(500, 'Failed to stream file'); } };