index.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. const os = require('os');
  2. const { app, session, BrowserWindow, ipcMain } = require('electron');
  3. const pie = require('puppeteer-in-electron');
  4. const puppeteer = require('puppeteer-core');
  5. const http = require('http');
  6. const Store = require('electron-store');
  7. const store = new Store();
  8. const urlRegex = 'http((?!http).){12,}?\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)|http((?!http).)*?video/tos*';
  9. async function trySniffer(url) {
  10. const promise = new Promise(async (resolve, reject) => {
  11. try {
  12. let timeout = setTimeout(() => {
  13. timeout = null;
  14. resolve({ code: 500 });
  15. page.close();
  16. }, 15000);
  17. const browser = await pie.connect(app, puppeteer);
  18. const window = new BrowserWindow({
  19. show: false,
  20. });
  21. // window.webContents.openDevTools();
  22. const page = await pie.getPage(browser, window);
  23. await page.setRequestInterception(true);
  24. page.on('request', (req) => {
  25. if (!timeout) req.abort().catch((err) => console.error(err));
  26. var reqUrl = req.url();
  27. if (reqUrl.match(urlRegex)) {
  28. if (reqUrl.indexOf('url=http') < 0 && reqUrl.indexOf('v=http') < 0 && reqUrl.indexOf('.css') < 0 && reqUrl.indexOf('.html') < 0) {
  29. console.log(req.headers());
  30. console.log(reqUrl);
  31. const headers = req.headers();
  32. const header = {};
  33. if (headers['referer']) header['referer'] = headers['referer'];
  34. if (headers['user-agent']) header['user-agent'] = headers['user-agent'];
  35. resolve({ code: 200, url: reqUrl, header: header });
  36. req.abort().catch((err) => console.error(err));
  37. clearTimeout(timeout);
  38. timeout = null;
  39. page.close();
  40. return;
  41. }
  42. }
  43. if (req.isInterceptResolutionHandled()) return;
  44. if (req.resourceType() == 'image') req.abort().catch((err) => console.error(err));
  45. else req.continue().catch((err) => console.error(err));
  46. });
  47. await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1');
  48. await page.goto(url).catch((err) => {});
  49. } catch (e) {
  50. console.error(e);
  51. resolve({ code: 500 });
  52. }
  53. });
  54. return promise;
  55. }
  56. pie.initialize(app);
  57. let httpServer = null;
  58. const httpServerSockets = new Set();
  59. const createMain = async () => {
  60. // await session.defaultSession.clearCache();
  61. const mainWindow = new BrowserWindow({
  62. show: false,
  63. width: 480,
  64. resizable: false,
  65. height: 300,
  66. webPreferences: {
  67. preload: __dirname + '/config.js',
  68. },
  69. });
  70. mainWindow.removeMenu();
  71. const defaultPort = 8889;
  72. function startServer() {
  73. if (httpServer) {
  74. return;
  75. }
  76. httpServerSockets.clear();
  77. const requestListener = async function (req, res) {
  78. if (!req.url.startsWith('/?url=')) {
  79. res.writeHead(500);
  80. res.end('Url must /?url=http*****');
  81. return;
  82. }
  83. const sniffUrl = req.url.substring(6).trim();
  84. const result = await trySniffer(sniffUrl);
  85. res.writeHead(200);
  86. res.end(JSON.stringify(result));
  87. };
  88. httpServer = http.createServer(requestListener);
  89. const port = store.get('port', defaultPort);
  90. store.set('port', port);
  91. httpServer.on('error', (e) => {
  92. httpServer = null;
  93. mainWindow.webContents.send('msg', {
  94. code: 201,
  95. });
  96. });
  97. httpServer.on('connection', (socket) => {
  98. httpServerSockets.add(socket);
  99. httpServer.once('close', () => {
  100. httpServerSockets.delete(socket);
  101. });
  102. });
  103. httpServer.listen(port, '0.0.0.0', () => {
  104. console.log(`Server is running on`);
  105. console.log(`\thttp://127.0.0.1:${port}`);
  106. const interfaces = os.networkInterfaces();
  107. for (let intf in interfaces) {
  108. for (let i in interfaces[intf]) {
  109. let address = interfaces[intf][i];
  110. if (address.family === 'IPv4' && !address.internal) {
  111. console.log(`\thttp://${address.address}:${port}`);
  112. }
  113. }
  114. }
  115. mainWindow.webContents.send('msg', {
  116. code: 200,
  117. });
  118. });
  119. }
  120. function stopServer() {
  121. if (httpServer) {
  122. for (const socket of httpServerSockets) {
  123. socket.destroy();
  124. httpServerSockets.delete(socket);
  125. }
  126. httpServer.close();
  127. httpServerSockets.clear();
  128. httpServer = null;
  129. }
  130. mainWindow.webContents.send('msg', {
  131. code: 201,
  132. });
  133. }
  134. // mainWindow.webContents.openDevTools();
  135. ipcMain.on('msg', async (event, msg) => {
  136. switch (msg.code) {
  137. case 100: {
  138. const port = store.get('port', defaultPort);
  139. mainWindow.webContents.send('msg', {
  140. code: 100,
  141. cfg: {
  142. port: port,
  143. },
  144. });
  145. startServer();
  146. break;
  147. }
  148. case 200: {
  149. const port = msg.cfg.port;
  150. store.set('port', port);
  151. startServer();
  152. break;
  153. }
  154. case 201:
  155. stopServer();
  156. break;
  157. default:
  158. break;
  159. }
  160. console.log(msg);
  161. });
  162. await mainWindow.loadFile(__dirname + '/config.html');
  163. mainWindow.show();
  164. };
  165. app.whenReady().then(() => {
  166. createMain();
  167. });
  168. app.on('window-all-closed', () => {
  169. if (process.platform !== 'darwin') {
  170. app.quit();
  171. }
  172. });