Created
January 17, 2025 20:17
-
-
Save selimtan/aa6963bdee07ff2b66342b8496968598 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express'); | |
const axios = require('axios'); | |
const app = express(); | |
async function curlRequest(url) { | |
try { | |
const response = await axios.get(url); | |
return response.data; | |
} catch (error) { | |
if (error.response) { | |
return null; | |
} else { | |
return null; | |
} | |
} | |
} | |
app.get('/m3u', async (req, res) => { | |
const { url, username, password, unwanted_groups = '' } = req.query; | |
if (!url || !username || !password) { | |
return res.status(400).send("Missing url, username, or password"); | |
} | |
const unwantedGroups = unwanted_groups.split(',').map(group => group.trim()); | |
const mainurlJson = await curlRequest(`${url}/player_api.php?username=${username}&password=${password}`); | |
if (!mainurlJson) { | |
return res.status(503).send("Unable to connect to the server. There might be an SSL certificate issue. Please check your URL and try again."); | |
} | |
let mainurlRaw = mainurlJson; | |
/* try { | |
mainurlRaw = JSON.parse(mainurlJson); | |
} catch (error) { | |
return res.status(500).send("Invalid response data from the server"); | |
} */ | |
if (!mainurlRaw.user_info || !mainurlRaw.server_info) { | |
return res.status(400).send("Invalid response data"); | |
} | |
const livechannelJson = await curlRequest(`${url}/player_api.php?username=${username}&password=${password}&action=get_live_streams`); | |
if (!livechannelJson) { | |
return res.status(503).send("Failed to retrieve live streams. There might be a connection issue."); | |
} | |
let livechannelRaw; | |
try { | |
livechannelRaw = livechannelJson; | |
} catch (error) { | |
return res.status(500).send("Invalid live streams data from the server"); | |
} | |
if (!Array.isArray(livechannelRaw)) { | |
return res.status(500).send("Invalid live streams data"); | |
} | |
const categoryJson = await curlRequest(`${url}/player_api.php?username=${username}&password=${password}&action=get_live_categories`); | |
if (!categoryJson) { | |
return res.status(503).send("Failed to retrieve live categories. There might be a connection issue."); | |
} | |
let categoryRaw; | |
try { | |
categoryRaw = categoryJson; | |
} catch (error) { | |
return res.status(500).send("Invalid live categories data from the server"); | |
} | |
if (!Array.isArray(categoryRaw)) { | |
return res.status(500).send("Invalid live categories data"); | |
} | |
const { user_info, server_info } = mainurlRaw; | |
const serverUrl = `http://${server_info.url}:${server_info.port}`; | |
const fullUrl = `${serverUrl}/live/${user_info.username}/${user_info.password}/`; | |
const categoryName = {}; | |
categoryRaw.forEach(cat => { | |
categoryName[cat.category_id] = cat.category_name; | |
}); | |
let m3uPlaylist = "#EXTM3U\n"; | |
livechannelRaw.forEach(channel => { | |
if (channel.stream_type === 'live') { | |
const groupTitle = categoryName[channel.category_id] || "Uncategorized"; | |
//if (!unwantedGroups.some(unwantedGroup => groupTitle.toLowerCase().includes(unwantedGroup.toLowerCase()))) { | |
const logoUrl = channel.stream_icon || ''; | |
m3uPlaylist += `#EXTINF:0 tvg-name="${channel.name}" group-title="${groupTitle}" tvg-logo="${logoUrl}",${channel.name}\n`; | |
m3uPlaylist += `${fullUrl}${channel.stream_id}.ts\n`; | |
// } | |
} | |
}); | |
res.setHeader("Content-Disposition", "attachment; filename=LiveStream.m3u"); | |
res.setHeader("Content-Type", "audio/x-scpls"); | |
res.send(m3uPlaylist); | |
}); | |
app.get('/movie', async (req, res) => { | |
const { url, username, password, unwanted_groups = '' } = req.query; | |
if (!url || !username || !password) { | |
return res.status(400).send("Missing url, username, or password"); | |
} | |
const unwantedGroups = unwanted_groups.split(',').map(group => group.trim()); | |
const mainurlJson = await curlRequest(`${url}/player_api.php?username=${username}&password=${password}`); | |
if (!mainurlJson) { | |
return res.status(503).send("Unable to connect to the server. There might be an SSL certificate issue. Please check your URL and try again."); | |
} | |
let mainurlRaw = mainurlJson; | |
if (!mainurlRaw.user_info || !mainurlRaw.server_info) { | |
return res.status(400).send("Invalid response data"); | |
} | |
const livechannelJson = await curlRequest(`${url}/player_api.php?username=${username}&password=${password}&action=get_vod_streams`); | |
if (!livechannelJson) { | |
return res.status(503).send("Failed to retrieve VOD streams. There might be a connection issue."); | |
} | |
let livechannelRaw = livechannelJson; | |
if (!Array.isArray(livechannelRaw)) { | |
return res.status(500).send("Invalid VOD streams data"); | |
} | |
const categoryJson = await curlRequest(`${url}/player_api.php?username=${username}&password=${password}&action=get_vod_categories`); | |
if (!categoryJson) { | |
return res.status(503).send("Failed to retrieve VOD categories. There might be a connection issue."); | |
} | |
let categoryRaw = categoryJson; | |
if (!Array.isArray(categoryRaw)) { | |
return res.status(500).send("Invalid VOD categories data"); | |
} | |
const { user_info, server_info } = mainurlRaw; | |
const serverUrl = `http://${server_info.url}:${server_info.port}`; | |
const fullUrl = `${serverUrl}/movie/${user_info.username}/${user_info.password}/`; | |
const categoryName = {}; | |
categoryRaw.forEach(cat => { | |
categoryName[cat.category_id] = cat.category_name; | |
}); | |
let m3uPlaylist = "#EXTM3U\n"; | |
livechannelRaw.forEach(channel => { | |
if (channel.stream_type === 'movie') { | |
const groupTitle = categoryName[channel.category_id] || "Uncategorized"; | |
//if (!unwantedGroups.some(unwantedGroup => groupTitle.toLowerCase().includes(unwantedGroup.toLowerCase()))) { | |
const logoUrl = channel.stream_icon || ''; | |
m3uPlaylist += `#EXTINF:0 tvg-name="${groupTitle} - ${channel.name}" group-title="${groupTitle}" tvg-logo="${logoUrl}",${groupTitle} - ${channel.name}\n`; | |
m3uPlaylist += `${fullUrl}${channel.stream_id}.${channel.container_extension}\n`; | |
// } | |
} | |
}); | |
res.setHeader("Content-Disposition", "attachment; filename=Movies.m3u"); | |
res.setHeader("Content-Type", "audio/x-scpls"); | |
res.send(m3uPlaylist); | |
}); | |
const PORT = process.env.PORT || 3000; | |
app.listen(PORT, () => { | |
console.log(`Server is running on port ${PORT}`); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment