File size: 4,105 Bytes
ece4c92
 
 
2f8dcb4
ece4c92
 
 
 
 
 
 
1a7be53
ece4c92
 
2f8dcb4
 
1a7be53
ffe37d1
 
1a7be53
 
 
ffe37d1
1a7be53
 
 
 
ece4c92
2f8dcb4
ad4d91f
7b1a290
2f8dcb4
78d43ad
ad4d91f
2f8dcb4
ad4d91f
2f8dcb4
ad4d91f
 
2f8dcb4
 
ad4d91f
2f8dcb4
 
 
 
 
 
6a31a3b
 
2f8dcb4
 
 
 
 
 
 
 
 
 
 
6a31a3b
 
 
 
ece4c92
 
 
ffe37d1
ece4c92
 
 
ffe37d1
ece4c92
2f8dcb4
6a31a3b
 
 
 
 
ece4c92
2f8dcb4
 
6a31a3b
2f8dcb4
 
6a31a3b
2f8dcb4
 
 
 
 
 
 
 
 
ece4c92
2f8dcb4
 
 
 
 
ece4c92
 
2f8dcb4
 
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
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");

// Ensure the downloads directory exists
if (!fs.existsSync(DOWNLOAD_DIR)) {
    fs.mkdirSync(DOWNLOAD_DIR, { recursive: true });
}

// Function to extract filename from URL
const getFileName = (fileUrl) => path.basename(new URL(fileUrl).pathname);

// 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 download file using aria2c (super fast)

const downloadFile = (fileUrl, filePath) => {
    return new Promise((resolve, reject) => {
        const aria2Command = `aria2c -x 16 -s 16 -k 1M --check-certificate=false -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);
        });
    });
};

// Function to convert MKV to MP4 using FFmpeg (Fast Conversion)
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);
        });
    });
};

// 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}`);

        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);

        // Start fast download with aria2c
        await downloadFile(fileUrl, originalFilePath);

        // 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 });

    } catch (error) {
        console.error("❌ Error:", error.message);
        return res.status(500).json({ error: "Download or conversion failed" });
    }
});

// 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}`);
});