import { t } from 'elysia' import yts from 'yt-search' const fetchCobaltAPI = async (body) => { const response = await fetch('https://c.blahaj.ca/', { method: 'POST', body: JSON.stringify(body), headers: { Accept: 'application/json', 'Content-Type': 'application/json' } }) return response.json() } const ytIdRegex = /(?:http(?:s|):\/\/|)(?:(?:www\.|)?youtube(?:\-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|\&)v=|embed\/|live\/|v\/)?|youtu\.be\/)([-_0-9A-Za-z]{11})/ const handleDownload = async (ctx) => { const { quality, type, url } = ctx.request.method !== 'GET' ? ctx.body : ctx.query if (!url) return ctx.error(400, { message: 'Missing url' }) const payload = { filenameStyle: 'pretty', url } if (type === 'audio') { payload.audioBitrate = quality || '128' payload.downloadMode = 'audio' } else payload.videoQuality = quality || '720' const result = await fetchCobaltAPI(payload) if (!result.url) return ctx.error(500, result.error) return ctx.redirect(result.url) } const handleSearch = async (ctx) => { const { query } = ctx.request.method !== 'GET' ? ctx.body : ctx.query if (!query) return ctx.error(400, { message: 'Missing query' }) const result = await yts(query) if (!result.all?.length) return ctx.error(500, { message: 'Video unavailable' }) return { success: true, data: result.all } } const handleSearchAndDownload = async (ctx) => { const { query } = ctx.request.method !== 'GET' ? ctx.body : ctx.query if (!query) return ctx.error(400, { message: 'Missing query' }) const id = ytIdRegex.exec(query)?.[1] let result = await yts(id ? { videoId: id } : query) result = result.videos ? result.videos[0] : result if (!result?.url) return ctx.error(500, { message: 'Video unavailable' }) const { origin, pathname } = new URL(ctx.url) const dlUrl = `${origin + pathname}/download?url=${result.url}` return { success: true, data: { ...result, download: { audio: `${dlUrl}&type=audio`, video: `${dlUrl}&type=video` } } } } const schemaJSON = { download: t.Object({ url: t.String(), type: t.Optional(t.String()), quality: t.Optional(t.String()) }), search: t.Object({ query: t.String() }) } export default (app) => app .group('', { detail: { tags: ['YouTube'] } }, (app) => app .get('', handleSearchAndDownload, { query: schemaJSON.search }) .post('', handleSearchAndDownload, { body: schemaJSON.search }) .get('/download', handleDownload, { query: schemaJSON.download }) .post('/download', handleDownload, { body: schemaJSON.download }) .get('/search', handleSearch, { query: schemaJSON.search }) .post('/search', handleSearch, { body: schemaJSON.search }) )