File size: 4,793 Bytes
ece4c92 1a7be53 6a31a3b ece4c92 1a7be53 ece4c92 1a7be53 ffe37d1 1a7be53 ffe37d1 1a7be53 ffe37d1 1a7be53 ece4c92 6a31a3b ece4c92 ffe37d1 ece4c92 ffe37d1 ece4c92 1a7be53 ece4c92 1a7be53 ece4c92 1a7be53 6a31a3b ece4c92 1a7be53 6a31a3b 1a7be53 ece4c92 6a31a3b c6e5396 6a31a3b ece4c92 ffe37d1 ece4c92 ffe37d1 ece4c92 ffe37d1 ece4c92 c6e5396 ece4c92 |
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 |
const express = require("express");
const axios = require("axios");
const fs = require("fs");
const path = require("path");
const https = require("https");
const { exec } = require("child_process"); // For FFmpeg execution
const app = express();
const PORT = 7860;
const DOWNLOAD_DIR = path.join(__dirname, "downloads");
// Ensure the downloads directory exists
if (!fs.existsSync(DOWNLOAD_DIR)) {
fs.mkdirSync(DOWNLOAD_DIR, { recursive: true });
}
// Axios instance to ignore SSL certificate verification
const axiosInstance = axios.create({
httpsAgent: new https.Agent({ rejectUnauthorized: false })
});
// Function to extract filename from URL or headers
const getFileName = (fileUrl, headers) => {
let filename = path.basename(new URL(fileUrl).pathname);
if (headers["content-disposition"]) {
const match = headers["content-disposition"].match(/filename="(.+)"/);
if (match) {
filename = match[1];
}
}
return filename.replace(/[<>:"/\\|?*]+/g, ""); // Remove invalid characters
};
// Function to delete file after a delay (default: 10 minutes)
const scheduleFileDeletion = (filePath, delay = 600000) => {
setTimeout(() => {
fs.unlink(filePath, (err) => {
if (!err) {
console.log(`β
Deleted file: ${filePath}`);
}
});
}, delay);
};
// Function to convert MKV to MP4 using FFmpeg
const convertToMp4 = (inputPath, outputPath) => {
return new Promise((resolve, reject) => {
const command = `ffmpeg -i "${inputPath}" -c:v copy -c:a aac -strict experimental "${outputPath}"`;
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`β FFmpeg error: ${error.message}`);
reject(error);
} else {
console.log(`β
Conversion complete: ${outputPath}`);
resolve(outputPath);
}
});
});
};
// API Route to download, convert, and serve .mp4 files
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}`);
// Request file with forced download handling
const response = await axiosInstance({
url: fileUrl,
method: "GET",
responseType: "stream",
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "*/*"
}
});
// Extract correct filename
const originalFilename = getFileName(fileUrl, response.headers);
const originalFilePath = path.join(DOWNLOAD_DIR, originalFilename);
// Determine new filename if conversion is needed
const isMkv = originalFilename.toLowerCase().endsWith(".mkv");
const mp4Filename = isMkv ? originalFilename.replace(/\.mkv$/, ".mp4") : originalFilename;
const mp4FilePath = path.join(DOWNLOAD_DIR, mp4Filename);
// Pipe response stream to file
const writer = fs.createWriteStream(originalFilePath);
response.data.pipe(writer);
writer.on("finish", async () => {
// Dynamically get the host URL from request headers
const hostUrl = `${req.protocol}://${req.get("host")}`;
if (isMkv) {
// Convert MKV to MP4
try {
await convertToMp4(originalFilePath, mp4FilePath);
fs.unlinkSync(originalFilePath); // Remove original MKV after conversion
} catch (error) {
return res.status(500).json({ error: "β Conversion failed" });
}
}
const servedUrl = `${hostUrl}/files/${mp4Filename}`;
scheduleFileDeletion(mp4FilePath); // Auto-delete after 10 minutes
console.log(`β
Download & conversion complete: ${servedUrl}`);
return res.json({ message: "Download & conversion complete", fileUrl: servedUrl });
});
writer.on("error", (err) => {
console.error("β Error writing file:", err);
return res.status(500).json({ error: "Error saving file" });
});
} catch (error) {
console.error("β Download error:", error.message);
return res.status(500).json({ error: "Failed to download file" });
}
});
// Serve files from downloads directory (publicly accessible)
app.use("/files", express.static(DOWNLOAD_DIR));
// Start the server
app.listen(PORT, () => {
console.log(`π Server running on port ${PORT}`);
}); |