Spaces:
Sleeping
Sleeping
Delete app
Browse files- app/actions.ts +0 -49
- app/api/download/route.ts +0 -46
- app/page.tsx +0 -10
app/actions.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
| 1 |
-
"use server"
|
| 2 |
-
|
| 3 |
-
import ytdl from "ytdl-core"
|
| 4 |
-
|
| 5 |
-
async function fetchYouTubeInfo(url: string) {
|
| 6 |
-
const info = await ytdl.getInfo(url)
|
| 7 |
-
return {
|
| 8 |
-
platform: "YouTube",
|
| 9 |
-
title: info.videoDetails.title,
|
| 10 |
-
formats: [
|
| 11 |
-
{
|
| 12 |
-
quality: "Alta calidad (720p)",
|
| 13 |
-
extension: "mp4",
|
| 14 |
-
url: `/api/download?url=${encodeURIComponent(url)}&format=mp4`,
|
| 15 |
-
},
|
| 16 |
-
{ quality: "Audio (MP3)", extension: "mp3", url: `/api/download?url=${encodeURIComponent(url)}&format=mp3` },
|
| 17 |
-
],
|
| 18 |
-
}
|
| 19 |
-
}
|
| 20 |
-
|
| 21 |
-
async function fetchGenericInfo(url: string, platform: string) {
|
| 22 |
-
return {
|
| 23 |
-
platform,
|
| 24 |
-
title: "Video",
|
| 25 |
-
formats: [{ quality: "Original", extension: "mp4", url: `/api/download?url=${encodeURIComponent(url)}` }],
|
| 26 |
-
}
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
export async function processUrl(url: string) {
|
| 30 |
-
try {
|
| 31 |
-
const cleanUrl = url.trim()
|
| 32 |
-
if (!cleanUrl) {
|
| 33 |
-
return { error: "Por favor, ingrese una URL válida." }
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
if (cleanUrl.includes("youtube.com") || cleanUrl.includes("youtu.be")) {
|
| 37 |
-
return await fetchYouTubeInfo(cleanUrl)
|
| 38 |
-
} else if (cleanUrl.includes("facebook.com")) {
|
| 39 |
-
return await fetchGenericInfo(cleanUrl, "Facebook")
|
| 40 |
-
} else if (cleanUrl.includes("twitter.com")) {
|
| 41 |
-
return await fetchGenericInfo(cleanUrl, "Twitter")
|
| 42 |
-
} else {
|
| 43 |
-
throw new Error("Plataforma no soportada")
|
| 44 |
-
}
|
| 45 |
-
} catch (error) {
|
| 46 |
-
return { error: "No se pudo procesar la URL. Asegúrese de que sea una URL de video válida." }
|
| 47 |
-
}
|
| 48 |
-
}
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/api/download/route.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
| 1 |
-
import { type NextRequest, NextResponse } from "next/server"
|
| 2 |
-
import ytdl from "ytdl-core"
|
| 3 |
-
import axios from "axios"
|
| 4 |
-
|
| 5 |
-
export async function GET(req: NextRequest) {
|
| 6 |
-
const url = req.nextUrl.searchParams.get("url")
|
| 7 |
-
const format = req.nextUrl.searchParams.get("format")
|
| 8 |
-
|
| 9 |
-
if (!url) {
|
| 10 |
-
return NextResponse.json({ error: "URL no proporcionada" }, { status: 400 })
|
| 11 |
-
}
|
| 12 |
-
|
| 13 |
-
try {
|
| 14 |
-
if (url.includes("youtube.com") || url.includes("youtu.be")) {
|
| 15 |
-
const info = await ytdl.getInfo(url)
|
| 16 |
-
const format_id = format === "mp3" ? "audioonly" : "highest"
|
| 17 |
-
const format_info = ytdl.chooseFormat(info.formats, { quality: format_id })
|
| 18 |
-
|
| 19 |
-
const stream = ytdl(url, { format: format_info })
|
| 20 |
-
const filename = `${info.videoDetails.title}.${format === "mp3" ? "mp3" : "mp4"}`
|
| 21 |
-
|
| 22 |
-
return new NextResponse(stream as any, {
|
| 23 |
-
headers: {
|
| 24 |
-
"Content-Disposition": `attachment; filename="${filename}"`,
|
| 25 |
-
"Content-Type": format === "mp3" ? "audio/mpeg" : "video/mp4",
|
| 26 |
-
},
|
| 27 |
-
})
|
| 28 |
-
} else {
|
| 29 |
-
// For other platforms, we'll use a more generic approach
|
| 30 |
-
const response = await axios.get(url, { responseType: "stream" })
|
| 31 |
-
const contentType = response.headers["content-type"]
|
| 32 |
-
const contentDisposition = response.headers["content-disposition"]
|
| 33 |
-
|
| 34 |
-
return new NextResponse(response.data, {
|
| 35 |
-
headers: {
|
| 36 |
-
"Content-Type": contentType,
|
| 37 |
-
"Content-Disposition": contentDisposition || "attachment",
|
| 38 |
-
},
|
| 39 |
-
})
|
| 40 |
-
}
|
| 41 |
-
} catch (error) {
|
| 42 |
-
console.error("Error downloading video:", error)
|
| 43 |
-
return NextResponse.json({ error: "Error al descargar el video" }, { status: 500 })
|
| 44 |
-
}
|
| 45 |
-
}
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/page.tsx
DELETED
|
@@ -1,10 +0,0 @@
|
|
| 1 |
-
import VideoDownloader from "../components/VideoDownloader"
|
| 2 |
-
|
| 3 |
-
export default function Home() {
|
| 4 |
-
return (
|
| 5 |
-
<main className="min-h-screen bg-gradient-to-br from-purple-400 to-indigo-600 flex items-center justify-center p-4">
|
| 6 |
-
<VideoDownloader />
|
| 7 |
-
</main>
|
| 8 |
-
)
|
| 9 |
-
}
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|