Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const express = require('express');
- const mongoose = require('mongoose');
- const cors = require('cors');
- const path = require('path');
- const methodOverride = require('method-override');
- const request = require('request');
- const restream = require('restream');
- const app = express();
- app.set('host', 'sportswatcher.ddns.net');
- const fs = require('fs');
- const fetch = require('node-fetch');
- app.use(express.json()); // Parse JSON bodies
- app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
- app.use(cors()); // Enable CORS
- app.use(methodOverride('_method')); // Enable method override
- // Replace with your MongoDB connection string
- const connectionString = 'mongodb://localhost:27017/streaming';
- // Connect to MongoDB
- mongoose
- .connect(connectionString, { useNewUrlParser: true, useUnifiedTopology: true })
- .then(() => {
- console.log('Connected to MongoDB');
- })
- .catch((error) => {
- console.error('Failed to connect to MongoDB', error);
- });
- // Define a Mongoose schema for our Game model
- const gameSchema = new mongoose.Schema({
- title: String,
- streamLink: String,
- sport: String,
- });
- // Create the Game model
- const Game = mongoose.model('Game', gameSchema);
- // Serve static files from the public directory
- app.use(express.static(path.join(__dirname, 'public')));
- const proxyAddress = 'http://localhost:8080/';
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
- // A function that returns a modified URL for .ts and .wbp files
- function getSegmentURL(targetURL) {
- const baseURL = getBaseURL();
- return baseURL + 'segment/' + targetURL.replace('https://', '');
- }
- // A function that returns a modified URL for .m3u8 files
- function getPlaylistURL(targetURL) {
- const baseURL = getBaseURL();
- return baseURL + 'proxy/' + targetURL.replace('https://', '');
- }
- app.use('/proxy/', async (req, res, next) => {
- const fullURL = req.protocol + '://' + req.get('host') + req.originalUrl;
- const { pathname, search } = new URL(fullURL);
- console.log(`Received request for URL: ${fullURL}`);
- const targetURL = pathname.replace('/proxy/', 'https://') + search;
- // Check if the request is for an m3u8 file
- if (path.extname(targetURL).toLowerCase() === '.m3u8') {
- try {
- const m3u8Response = await fetch(targetURL, {
- headers: {
- 'accept': '*/*',
- 'accept-encoding': 'gzip, deflate, br',
- 'origin': 'https://ddhwebcast4k.xyz',
- 'referer': 'https://ddhwebcast4k.xyz/',
- 'sec-fetch-mode': 'cors',
- 'sec-fetch-site': 'cross-site',
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
- 'authority' : 'ddh1.cdndac.lol'
- }
- });
- let m3u8Content = await m3u8Response.text();
- // Modify the .ts and .wbp URLs in the m3u8 content
- m3u8Content = m3u8Content.split('\n').map(line => {
- if (line.endsWith('.ts') || line.endsWith('.wbp')) {
- // Check if the segment link is relative or absolute
- if (line.startsWith('http')) {
- // Absolute link, use getSegmentURL function
- return getSegmentURL(line);
- } else {
- // Relative link, append to the targetURL's base path
- const basePath = targetURL.substring(0, targetURL.lastIndexOf('/') + 1);
- return getSegmentURL(basePath + line);
- }
- } else if (line.endsWith('.m3u8')) {
- // Check if the playlist link is relative or absolute
- if (line.startsWith('http')) {
- // Absolute link, use getPlaylistURL function
- return getPlaylistURL(line);
- } else {
- // Relative link, append to the targetURL's base path
- const basePath = targetURL.substring(0, targetURL.lastIndexOf('/') + 1);
- return getPlaylistURL(basePath + line);
- }
- } else {
- return line;
- }
- }).join('\n');
- res.setHeader('Content-Type', 'application/x-mpegURL');
- res.setHeader('Access-Control-Allow-Origin', '*');
- res.send(m3u8Content);
- } catch (err) {
- console.error('Failed to fetch m3u8:', err.message);
- res.status(500).send('Proxy Error');
- }
- return;
- }
- const proxyRequestOptions = {
- url: targetURL
- };
- const proxyRequest = request(proxyRequestOptions);
- proxyRequest.on('response', async function(sourceResponse) {
- // Diagnostic log to check the status code and the file extension
- console.log(`Status code: ${sourceResponse.statusCode}, File extension: ${path.extname(targetURL).toLowerCase()}`);
- if (path.extname(targetURL).toLowerCase() === '.ts' && sourceResponse.statusCode >= 300 && sourceResponse.statusCode < 400) {
- const redirectTo = sourceResponse.headers['location'];
- console.log(`Redirection detected for ${targetURL} -> ${redirectTo}`);
- // Diagnostic log to check the redirect location
- console.log(`Redirect detected to: ${redirectTo}`);
- if (redirectTo && path.extname(redirectTo).toLowerCase() === '.js') {
- try {
- console.log('Attempting to fetch the .js video data...'); // Diagnostic log
- const jsResponse = await fetch(redirectTo);
- const videoData = await jsResponse.buffer();
- res.setHeader('Content-Type', 'video/MP2T');
- res.setHeader('Access-Control-Allow-Origin', '*');
- res.send(videoData);
- return;
- } catch (err) {
- console.error('Failed to fetch .js video data:', err.message);
- res.status(500).send('Proxy Error');
- return;
- }
- }
- }
- Object.keys(sourceResponse.headers).forEach(headerKey => {
- res.setHeader(headerKey, sourceResponse.headers[headerKey]);
- });
- let contentType = sourceResponse.headers['content-type'];
- if (!contentType || contentType === 'application/octet-stream') {
- const extname = path.extname(targetURL).toLowerCase();
- if (extname === '.m4s') {
- res.setHeader('Content-Type', 'application/dash+xml');
- } else if (extname === '.ts') {
- res.setHeader('Content-Type', 'video/MP2T');
- } else if (extname === '.wbp') {
- res.setHeader('Content-Type', 'video/webm');
- } else {
- res.setHeader('Content-Type', 'application/x-mpegURL');
- }
- }
- res.setHeader('Access-Control-Allow-Origin', '*');
- sourceResponse.pipe(res);
- });
- proxyRequest.on('error', function(err) {
- console.error('Proxy Error for URL:', targetURL, 'Error:', err.message);
- res.status(500).send('Proxy Error');
- });
- res.on('error', (err) => {
- console.error('Error during response pipe:', err);
- });
- req.pipe(restream()).pipe(proxyRequest);
- });
- // A new route for handling .ts and .wbp requests
- app.use('/segment/*', (req, res) => {
- const fullURL = req.protocol + '://' + req.get('host') + req.originalUrl;
- console.log(`Received request for URL: ${fullURL}`);
- // Capture the segment path from the wildcard
- const segmentPath = req.params[0];
- // Construct the targetURL with the captured segment path
- const targetURL = 'https://' + segmentPath;
- // Create a proxyRequestOptions object with the headers copied from the original request
- const proxyRequestOptions = {
- url: targetURL,
- headers: {
- 'accept': '*/*',
- 'accept-encoding': 'gzip, deflate, br',
- 'origin': 'https://ddhwebcast4k.xyz',
- 'referer': 'https://ddhwebcast4k.xyz/',
- 'sec-fetch-mode': 'cors',
- 'sec-fetch-site': 'cross-site',
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
- 'authority' : 'ddh1.cdndac.lol'
- }
- };
- // Set the host header to match the target URL's host
- proxyRequestOptions.headers.host = new URL(targetURL).host;
- const proxyRequest = request(proxyRequestOptions);
- proxyRequest.on('response', function(sourceResponse) {
- Object.keys(sourceResponse.headers).forEach(headerKey => {
- res.setHeader(headerKey, sourceResponse.headers[headerKey]);
- });
- let contentType = sourceResponse.headers['content-type'];
- if (!contentType || contentType === 'application/octet-stream') {
- const extname = path.extname(targetURL).toLowerCase();
- if (extname === '.ts') {
- res.setHeader('Content-Type', 'video/MP2T');
- } else if (extname === '.wbp') {
- res.setHeader('Content-Type', 'video/webm'); // Assume webm format for .wbp files
- }
- }
- res.setHeader('Access-Control-Allow-Origin', '*');
- sourceResponse.pipe(res);
- });
- proxyRequest.on('error', function(err) {
- console.error('Proxy Error for URL:', targetURL, 'Error:', err.message);
- res.status(500).send('Proxy Error');
- });
- res.on('error', (err) => {
- console.error('Error during response pipe:', err);
- });
- req.pipe(restream()).pipe(proxyRequest);
- });
- function getBaseURL() {
- return `http://${app.get('host')}/`;
- }
- app.get('/', (req, res) => {
- res.render('main.ejs');
- });
- // Route for serving the admin panel
- app.get('/admin', async (req, res) => {
- try {
- const games = await Game.find();
- res.render('admin.ejs', { videos: games });
- } catch (error) {
- res.status(500).send(error);
- }
- });
- // Route for getting all games
- app.get('/games', async (req, res) => {
- try {
- const games = await Game.find();
- res.send(games);
- } catch (error) {
- res.status(500).send(error);
- }
- });
- // Route for creating a new game
- app.post('/games', async (req, res) => {
- try {
- const game = new Game(req.body);
- await game.save();
- res.redirect('/admin');
- } catch (error) {
- res.status(500).send(error);
- }
- });
- app.put('/games/:id', async (req, res) => {
- try {
- const { id } = req.params;
- const { title, streamLink, sport } = req.body;
- const updatedGame = await Game.findByIdAndUpdate(id, { title, streamLink, sport }, { new: true });
- res.redirect('/admin');
- } catch (error) {
- res.status(500).send(error);
- }
- });
- // Route for deleting a game
- app.delete('/games/:id', async (req, res) => {
- try {
- await Game.deleteOne({ _id: req.params.id });
- res.redirect('/admin');
- } catch (error) {
- res.status(500).send(error);
- }
- });
- // Start the server
- const port = process.env.PORT || 3000;
- app.listen(port, () => console.log(`Server running on port ${port}`));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement