Advertisement
samipote

Untitled

Aug 26th, 2023
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.56 KB | None | 0 0
  1. process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
  2. const express = require('express');
  3. const mongoose = require('mongoose');
  4. const cors = require('cors');
  5. const path = require('path');
  6. const methodOverride = require('method-override');
  7. const axios = require('axios'); // Import axios
  8. const app = express();
  9. app.set('host', 'sportswatcher.ddns.net');
  10. const fs = require('fs');
  11. const fetch = require('node-fetch');
  12. app.use(express.json()); // Parse JSON bodies
  13. app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
  14. app.use(cors()); // Enable CORS
  15. app.use(methodOverride('_method')); // Enable method override
  16. const https = require('https');
  17. const agent = new https.Agent({
  18. rejectUnauthorized: false // or 'TLSv1_3_method', 'TLSv1_1_method', 'TLSv1_method'
  19. });
  20. // Replace with your MongoDB connection string
  21. const connectionString = 'mongodb://localhost:27017/streaming';
  22. // Connect to MongoDB
  23. mongoose
  24. .connect(connectionString, { useNewUrlParser: true, useUnifiedTopology: true, })
  25. .then(() => {
  26. console.log('Connected to MongoDB');
  27. })
  28. .catch((error) => {
  29. console.error('Failed to connect to MongoDB', error);
  30. });
  31. // Define a Mongoose schema for our Game model
  32. const gameSchema = new mongoose.Schema({
  33. title: String,
  34. streamLink: String,
  35. sport: String,
  36. });
  37. // Create the Game model
  38. const Game = mongoose.model('Game', gameSchema);
  39. // Serve static files from the public directory
  40. app.use(express.static(path.join(__dirname, 'public')));
  41. const proxyAddress = 'http://localhost:8080/';
  42. // A function that returns a modified URL for .ts files
  43. function getTSURL(targetURL) {
  44. const baseURL = getBaseURL();
  45. return baseURL + 'ts/' + targetURL.replace('https://', '');
  46. }
  47. function resolveURL(base, relative) {
  48. const baseURL = new URL(base);
  49. return new URL(relative, baseURL).toString();
  50. }
  51. app.use('/proxy/', async (req, res, next) => {
  52. const fullURL = req.protocol + '://' + req.get('host') + req.originalUrl;
  53. const { pathname, search } = new URL(fullURL);
  54. console.log(`Received request for URL: ${fullURL}`);
  55. const targetURL = pathname.replace('/proxy/', 'https://') + search;
  56. if (path.extname(targetURL).toLowerCase() === '.m3u8') {
  57. try {
  58. const m3u8Response = await fetch(targetURL);
  59. let m3u8Content = await m3u8Response.text();
  60. m3u8Content = m3u8Content.split('\n').map(line => {
  61. if (line.endsWith('.ts')) {
  62. const tsURL = line.startsWith('http') ? line : resolveURL(targetURL, line);
  63. return getTSURL(tsURL);
  64. } else {
  65. return line;
  66. }
  67. }).join('\n');
  68. res.setHeader('Content-Type', 'application/vnd.apple.mpegurl');
  69. res.setHeader('Access-Control-Allow-Origin', '*');
  70. res.send(m3u8Content);
  71. } catch (err) {
  72. console.error('Failed to fetch m3u8:', err.message);
  73. res.status(500).send('Proxy Error');
  74. }
  75. return;
  76. }
  77. // Use axios instead of request and restream
  78. try {
  79. const proxyResponse = await axios.get(targetURL, {
  80. headers: { ...req.headers },
  81. httpsAgent: agent
  82. });
  83. Object.keys(proxyResponse.headers).forEach(headerKey => {
  84. res.setHeader(headerKey, proxyResponse.headers[headerKey]);
  85. });
  86. let contentType = proxyResponse.headers['content-type'];
  87. if (!contentType || contentType === 'application/octet-stream') {
  88. const extname = path.extname(targetURL).toLowerCase();
  89. if (extname === '.m4s') {
  90. res.setHeader('Content-Type', 'application/dash+xml');
  91. } else if (extname === '.ts') {
  92. res.setHeader('Content-Type', 'video/MP2T');
  93. } else {
  94. res.setHeader('Content-Type', 'application/x-mpegURL');
  95. }
  96. }
  97. res.setHeader('Access-Control-Allow-Origin', '*');
  98. proxyResponse.data.pipe(res); // Pipe the data stream to the response
  99. } catch (err) {
  100. console.error('Proxy Error for URL:', targetURL, 'Error:', err.message);
  101. res.status(500).send('Proxy Error');
  102. }
  103. });
  104. // A new route for handling .ts requests
  105. app.use('/ts/', async (req, res) => { // Use async function
  106. const fullURL = req.protocol + '://' + req.get('host') + req.originalUrl;
  107. const { pathname, search } = new URL(fullURL);
  108. console.log(`Received request for URL: ${fullURL}`);
  109. const targetURL = pathname.replace('/ts/', 'https://') + search;
  110. // Use axios instead of request and restream
  111. try {
  112. const proxyResponse = await axios.get(targetURL, {
  113. headers: { ...req.headers },
  114. httpsAgent: agent
  115. });
  116. Object.keys(proxyResponse.headers).forEach(headerKey => {
  117. res.setHeader(headerKey, proxyResponse.headers[headerKey]);
  118. });
  119. let contentType = proxyResponse.headers['content-type'];
  120. if (!contentType || contentType === 'application/octet-stream') {
  121. res.setHeader('Content-Type', 'video/MP2T');
  122. }
  123. res.setHeader('Access-Control-Allow-Origin', '*');
  124. proxyResponse.data.pipe(res); // Pipe the data stream to the response
  125. } catch (err) {
  126. console.error('Proxy Error for URL:', targetURL, 'Error:', err.message);
  127. res.status(500).send('Proxy Error');
  128. }
  129. });
  130. function getBaseURL() {
  131. return `http://${app.get('host')}/`;
  132. }
  133. app.get('/', (req, res) => {
  134. res.render('main.ejs');
  135. });
  136. // Route for serving the admin panel
  137. app.get('/admin', async (req, res) => {
  138. try {
  139. const games = await Game.find();
  140. res.render('admin.ejs', { videos: games });
  141. } catch (error) {
  142. res.status(500).send(error);
  143. }
  144. });
  145. // Route for getting all games
  146. app.get('/games', async (req, res) => {
  147. try {
  148. const games = await Game.find();
  149. res.send(games);
  150. } catch (error) {
  151. res.status(500).send(error);
  152. }
  153. });
  154. // Route for creating a new game
  155. app.post('/games', async (req, res) => {
  156. try {
  157. const game = new Game(req.body);
  158. await game.save();
  159. res.redirect('/admin');
  160. } catch (error) {
  161. res.status(500).send(error);
  162. }
  163. });
  164. app.put('/games/:id', async (req, res) => {
  165. try {
  166. const { id } = req.params;
  167. const { title, streamLink, sport } = req.body;
  168. const updatedGame = await Game.findByIdAndUpdate(id, { title, streamLink, sport }, { new: true });
  169. res.redirect('/admin');
  170. } catch (error) {
  171. res.status(500).send(error);
  172. }
  173. });
  174. // Route for deleting a game
  175. app.delete('/games/:id', async (req, res) => {
  176. try {
  177. await Game.deleteOne({ _id: req.params.id });
  178. res.redirect('/admin');
  179. } catch (error) {
  180. res.status(500).send(error);
  181. }
  182. });
  183. // Start the server
  184. const port = process.env.PORT || 3000;
  185. app.listen(port, () => console.log(`Server running on port ${port}`));
  186.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement