File size: 4,215 Bytes
dd3d0dc
 
 
8d7e89a
dd3d0dc
3e072a2
 
 
dd3d0dc
 
8d7e89a
dd3d0dc
 
 
8d7e89a
dd3d0dc
3e072a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8d7e89a
 
 
3e072a2
8d7e89a
 
 
 
 
 
 
 
 
 
 
 
 
 
dd3d0dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8d7e89a
dd3d0dc
 
 
 
3e072a2
dd3d0dc
 
 
 
 
 
 
3e072a2
 
8d7e89a
3e072a2
 
 
 
 
 
 
 
 
 
 
 
 
 
dd3d0dc
3e072a2
 
8d7e89a
3e072a2
 
 
 
 
 
 
 
 
 
 
 
dd3d0dc
8d7e89a
 
 
 
 
 
 
 
 
dd3d0dc
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const express = require("express")
const path = require("path")
const ytdl = require("ytdl-core")
const ytdlDiscord = require("ytdl-core-discord")
const axios = require("axios")
const { exec } = require("yt-dlp-exec")
const fs = require("fs")
const os = require("os")

const app = express()
const port = process.env.PORT || 7860

app.use(express.static(path.join(__dirname, "public")))

async function getYoutubeInfo(url) {
  try {
    const info = await exec(url, {
      dumpSingleJson: true,
      noCheckCertificates: true,
      noWarnings: true,
      preferFreeFormats: true,
      addHeader: ["referer:youtube.com", "user-agent:googlebot"],
    })

    const parsedInfo = JSON.parse(info)

    return {
      platform: "YouTube",
      title: parsedInfo.title,
      formats: [
        {
          quality: "Alta calidad (720p)",
          extension: "mp4",
          url: `/api/download?url=${encodeURIComponent(url)}&format=mp4`,
        },
        { quality: "Audio (MP3)", extension: "mp3", url: `/api/download?url=${encodeURIComponent(url)}&format=mp3` },
      ],
    }
  } catch (error) {
    console.error("YouTube processing error:", error)
    throw new Error("No se pudo procesar el video de YouTube. Por favor, intente de nuevo más tarde.")
  }
}

app.get("/api/info", async (req, res) => {
  const { url } = req.query

  if (!url) {
    return res.status(400).json({ error: "URL no proporcionada" })
  }

  try {
    if (url.includes("youtube.com") || url.includes("youtu.be")) {
      const info = await getYoutubeInfo(url)
      res.json(info)
    } else if (url.includes("facebook.com")) {
      res.json({
        platform: "Facebook",
        title: "Video de Facebook",
        formats: [{ quality: "Original", extension: "mp4", url: `/api/download?url=${encodeURIComponent(url)}` }],
      })
    } else if (url.includes("twitter.com")) {
      res.json({
        platform: "Twitter",
        title: "Video de Twitter",
        formats: [{ quality: "Original", extension: "mp4", url: `/api/download?url=${encodeURIComponent(url)}` }],
      })
    } else {
      res.status(400).json({ error: "Plataforma no soportada" })
    }
  } catch (error) {
    console.error("Error processing URL:", error)
    res.status(500).json({ error: error.message || "Error al procesar la URL" })
  }
})

app.get("/api/download", async (req, res) => {
  const { url, format } = req.query

  if (!url) {
    return res.status(400).json({ error: "URL no proporcionada" })
  }

  try {
    if (url.includes("youtube.com") || url.includes("youtu.be")) {
      const tempDir = os.tmpdir()
      const outputTemplate = path.join(tempDir, "video.%(ext)s")

      const ytDlpOptions = [
        url,
        "-f",
        format === "mp3" ? "bestaudio" : "best[height<=720]",
        "-o",
        outputTemplate,
        "--no-check-certificates",
        "--no-warnings",
        "--prefer-free-formats",
        "--add-header",
        "referer:youtube.com",
        "--add-header",
        "user-agent:googlebot",
      ]

      if (format === "mp3") {
        ytDlpOptions.push("--extract-audio", "--audio-format", "mp3")
      }

      await exec(ytDlpOptions)

      const downloadedFile = format === "mp3" ? path.join(tempDir, "video.mp3") : path.join(tempDir, "video.mp4")

      res.download(downloadedFile, (err) => {
        if (err) {
          console.error("Download error:", err)
          res.status(500).json({ error: "Error al descargar el archivo" })
        }
        fs.unlinkSync(downloadedFile)
      })
    } else {
      try {
        const response = await axios.get(url, { responseType: "stream" })
        res.header("Content-Type", response.headers["content-type"])
        res.header("Content-Disposition", response.headers["content-disposition"] || "attachment")
        response.data.pipe(res)
      } catch (error) {
        console.error("Download error:", error)
        res.status(500).json({ error: "Error al descargar el video" })
      }
    }
  } catch (error) {
    console.error("Error downloading video:", error)
    res.status(500).json({ error: "Error al descargar el video" })
  }
})

app.listen(port, () => {
  console.log(`Server is running on port ${port}`)
})