| const express = require("express"); |
| const fs = require("fs"); |
| const path = require("path"); |
| const { exec } = require("child_process"); |
|
|
| const app = express(); |
| const PORT = 7860; |
| const DOWNLOAD_DIR = path.join(__dirname, "downloads"); |
|
|
| |
| if (!fs.existsSync(DOWNLOAD_DIR)) { |
| fs.mkdirSync(DOWNLOAD_DIR, { recursive: true }); |
| } |
|
|
| |
| const getFileName = (fileUrl) => path.basename(new URL(fileUrl).pathname); |
|
|
| |
| const scheduleFileDeletion = (filePath, delay = 600000) => { |
| setTimeout(() => { |
| fs.unlink(filePath, (err) => { |
| if (!err) { |
| console.log(`β
Deleted file: ${filePath}`); |
| } |
| }); |
| }, delay); |
| }; |
|
|
| |
|
|
| const downloadFile = (fileUrl, filePath) => { |
| return new Promise((resolve, reject) => { |
| const aria2Command = `aria2c --allow-insecure -x 16 -s 16 -k 1M -o "${filePath}" "${fileUrl}"`; |
| console.log(`π Starting fast download: ${aria2Command}`); |
|
|
| exec(aria2Command, (error, stdout, stderr) => { |
| if (error) { |
| console.error(`β Aria2 Error: ${error.message}`); |
| console.error(`π΄ STDERR: ${stderr}`); |
| return reject(error); |
| } |
| console.log(`β
Aria2 Output: ${stdout || stderr}`); |
| resolve(filePath); |
| }); |
| }); |
| }; |
|
|
| |
| const convertToMp4 = (inputPath, outputPath) => { |
| return new Promise((resolve, reject) => { |
| const ffmpegCmd = `ffmpeg -i "${inputPath}" -c:v copy -c:a aac -b:a 192k -y "${outputPath}"`; |
| console.log(`π Running FFmpeg: ${ffmpegCmd}`); |
|
|
| exec(ffmpegCmd, (error, stdout, stderr) => { |
| if (error) { |
| console.error(`β FFmpeg Error: ${error.message}`); |
| return reject(error); |
| } |
| console.log(`β
FFmpeg Output: ${stdout || stderr}`); |
| resolve(outputPath); |
| }); |
| }); |
| }; |
|
|
| |
| app.get("/download", async (req, res) => { |
| const fileUrl = req.query.url; |
| if (!fileUrl) { |
| return res.status(400).json({ error: "β Missing URL parameter" }); |
| } |
|
|
| try { |
| console.log(`β¬οΈ Downloading: ${fileUrl}`); |
|
|
| const originalFilename = getFileName(fileUrl); |
| const originalFilePath = path.join(DOWNLOAD_DIR, originalFilename); |
|
|
| const isMkv = originalFilename.toLowerCase().endsWith(".mkv"); |
| const mp4Filename = isMkv ? originalFilename.replace(/\.mkv$/, ".mp4") : originalFilename; |
| const mp4FilePath = path.join(DOWNLOAD_DIR, mp4Filename); |
|
|
| |
| await downloadFile(fileUrl, originalFilePath); |
|
|
| |
| const hostUrl = `${req.protocol}://${req.get("host")}`; |
|
|
| if (isMkv) { |
| |
| try { |
| await convertToMp4(originalFilePath, mp4FilePath); |
| fs.unlinkSync(originalFilePath); |
| } catch (error) { |
| return res.status(500).json({ error: "β Conversion failed" }); |
| } |
| } |
|
|
| const servedUrl = `${hostUrl}/files/${mp4Filename}`; |
| scheduleFileDeletion(mp4FilePath); |
|
|
| console.log(`β
Download & conversion complete: ${servedUrl}`); |
| return res.json({ message: "Download & conversion complete", fileUrl: servedUrl }); |
|
|
| } catch (error) { |
| console.error("β Error:", error.message); |
| return res.status(500).json({ error: "Download or conversion failed" }); |
| } |
| }); |
|
|
| |
| app.use("/files", express.static(DOWNLOAD_DIR)); |
|
|
| |
| app.listen(PORT, () => { |
| console.log(`π Server running on port ${PORT}`); |
| }); |