Twitch m3u8

node v15.14.0
version: 3.1.2
endpointsharetweet
https://tinyurl.com/twitchm3u8 ?c=channel&q=quality //0 = source
const twitch = require("twitch-m3u8"); var tonicExpress = require("@runkit/runkit/express-endpoint/1.0.0"); var app = tonicExpress(module.exports); //fetchretry+htmlparser var originalFetch = require('isomorphic-fetch'); var fetch = require('fetch-retry')(originalFetch); var HTMLParser = require('node-html-parser'); var cookieParser = require('cookie-parser'); // app.use(cookieParser()); app.get('/', async(req, res) => { //query let quality = parseInt(req.query.q, 10);//0 = source let channel = req.query.c; //check channel if ( channel == "" || channel === undefined ){ console.log(channel,'channel undefined'); //res.end('url/?c=channel&q=quality //0 = source'); channel = "Twitch" }; let weburl = "https://www.twitch.tv/" + channel; //cookies function onlyUnique(value, index, self) { return self.indexOf(value) === index; }; let recenti = req.cookies.recent if (!recenti){ recenti = []} recenti.unshift(channel); recenti = recenti.filter(onlyUnique); if (recenti.length > 6) recenti.length = 6; console.log(recenti) res.cookie('recent', recenti, {encode: String, maxAge: 7 * 24 * 3600000}); recenti.shift(); //get m3u8 let errore let streams = await twitch.getStream(channel.toLowerCase()).catch(err => errore = err); console.log("Errore:"+errore); //fetch meta title, image let feci = await fetch(weburl, { retryOn: async function(attempt, error, response) { if (attempt > 2) return false; //console.log("fetch-retry attempt "+ attempt); let fecitext = await response.text(); let root = await HTMLParser.parse(fecitext); image = await root.querySelector("meta[property='og:image']").getAttribute("content"); description = await root.querySelector("meta[property='og:description']").getAttribute("content"); console.log(description); if (description == "Twitch is the world's leading video platform and community for gamers.") { console.log(`retrying, attempt number ${attempt + 1}`); return true; } } }); //console.log("di Nuovo"+description); //console.log("feci:"+feci); //.then(function(response) { //return response.text(); //}); //direct with quality query if (quality >= 0){ console.log(`redirecting to ${channel} quality ${quality}`) res.redirect(streams[quality].url); } else { console.log(`Creating html for ${channel}`); let html = `<!DOCTYPE html> <head> <title>Twitch m3u8 - ${channel}</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway"> <link rel="icon" type="image/png" sizes="32x32" href="https://static.twitchcdn.net/assets/favicon-32-e29e246c157142c94346.png"> <link rel="icon" type="image/png" sizes="16x16" href="https://static.twitchcdn.net/assets/favicon-16-52e571ffea063af7a7f4.png"> <style> body,h1 {font-family: "Raleway", sans-serif} body, html {height: 100%} .bgimg { background-color: rgb(107, 91, 149); min-height: 100%; //background-image: url('https://wallpaperaccess.com/full/268724.jpg'); //background-position: center; //background-size: cover; } form { position: absolute; top: 12px; right: 24px; background-color: #493e66; width: 300px; height: 44px; border-radius: 5px; display: flex; flex-direction: row; align-items: center; } input { all: unset; font: 16px system-ui; color: #fff; height: 100%; width: 100%; padding: 6px 10px; } button { all: unset; cursor: pointer; width: 44px; height: 44px; } ::placeholder { color: #fff; opacity: 0.7; } svg { color: #fff; fill: currentColor; width: 24px; height: 24px; padding: 10px; } </style> </head> <body> <div class="bgimg w3-display-container w3-animate-opacity w3-text-white"> <div class="w3-display-topleft w3-padding-large w3-xlarge w3-hover-text-black"> <img src="https://static.twitchcdn.net/assets/favicon-32-e29e246c157142c94346.png" alt="Icon" width="32" height="32"> <a style="text-decoration:none" href="https://runkit.com/alexbestbro/twitch" target="_blank">Twitch m3u8</a> </div> <form id="form" class="w3-padding-large w3-xlarge"> <input type="search" id="query" name="c" placeholder="Search..." list="myList" required > <button><svg viewBox="0 0 1024 1024"><path class="path1" d="M848.471 928l-263.059-263.059c-48.941 36.706-110.118 55.059-177.412 55.059-171.294 0-312-140.706-312-312s140.706-312 312-312c171.294 0 312 140.706 312 312 0 67.294-24.471 128.471-55.059 177.412l263.059 263.059-79.529 79.529zM189.623 408.078c0 121.364 97.091 218.455 218.455 218.455s218.455-97.091 218.455-218.455c0-121.364-103.159-218.455-218.455-218.455-121.364 0-218.455 97.091-218.455 218.455z"></path></svg></button> <datalist id="myList">` for (let y of recenti){ html += `<option value="${y}"></option>` } html += `</datalist> </form> <div class="w3-display-middle w3-center" style="margin-top: 10px;"> <img src="${image}" class="w3-animate-top" width="150" height="150" style="border-radius: 50%"> <h1 class="w3-xxxlarge w3-animate-top w3-hover-text-black"> <a style="text-decoration:none" href="${weburl}" target="_blank"> <b>${channel}</b> </a> </h1> <a class="w3-mobile style="text-decoration:none">${description}</a> <hr class="w3-border-white" style="margin:auto;width:100%"> <p class="w3-large w3-center w3-mobile w3-animate-bottom">` if (!errore){ for (let x of streams){ html += `<a class="w3-mobile w3-hover-text-black" style="text-decoration:none" href="javascript:window.open('${x.url}','_blank','toolbar=0,width=1498,height=988,left=0');">${x.quality}</a>&emsp;` } html += `</p> <p class="w3-large w3-center w3-mobile w3-animate-bottom"> <a class="w3-mobile w3-hover-text-black" style="text-decoration:none" href="javascript:window.open('https://www.twitch.tv/popout/${channel}/chat?popout=','_blank','toolbar=no,width=400,height=988,left=1500');">Chat_only</a>&emsp; <a class="w3-mobile w3-hover-text-black" style="text-decoration:none" href="javascript:window.open('https://runkit.io/alexbestbro/twitch-test/branches/master?chatsize=18&c=${channel}','_self');">Source+Chat</a><br>` }else{html += `${errore}<br>`}; html += `</p> </div> </div> </body> </html>` res.end(html); } });
//to do: //toggle chat //splash -quasi //embed con query //colore sfondo //reload + query (fetch retry da provare) -fatto //?cookie recenti? -fatto //lowercase -fatto //titolo, immagine, errore -fatto /error page -fatto //link tv aggiornato -fatto //twitch test embed tv -fatto
Loading…

no comments

    sign in to comment