pub / tw2html

Checks online status of streams on twitch.tv and lets you watch them
git clone https://src.jayvii.de/pub/tw2html.git
Home | Log | Files | Exports | Refs | README | RSS

twitch.js (6132B)


      1 async function twitch_check_online(stream) {
      2 
      3   // Construct request
      4   const status_url = new Request(
      5 	  "https://static-cdn.jtvnw.net/previews-ttv/live_user_" + stream +
      6 	  "-853x480.jpg"
      7   );
      8 
      9   // Get HTTP status code of status_url
     10   const response_url = await fetch(status_url).then((response) => {
     11   	return response;
     12   });
     13 
     14   // refer online status from whether a redirect happened
     15   const status = (status_url.url === response_url.url);
     16 
     17   // return online status
     18   return(status);
     19 
     20 }
     21 
     22 async function tw2html_toggle_hidden(stream) {
     23 
     24 	// get stream section
     25 	var section = document.getElementById("stream_" + stream);
     26 
     27 	// check online status of stream
     28 	const status = await twitch_check_online(stream);
     29 
     30 	// Debug output
     31 	console.log("Stream: " + stream + " | Status: " + status);
     32 
     33 	// If stream is online, unhide it. If it is offline, hide it
     34 	if (status) {
     35 
     36 		// Unhide section
     37 		section.classList.remove("hidden");
     38 
     39 		// Check whether player exists
     40 		var player = section.querySelectorAll("#player_" + stream);
     41 
     42 		// Update preview image if player does NOT exist
     43 		if (player.length < 1) {
     44 			tw2html_update_preview(stream);
     45 		}
     46 
     47 		// Fetch description text
     48 		var desc_txt = await tw2html_fetch_description(stream);
     49 
     50 	} else {
     51 
     52 		// Hide section
     53 		section.classList.add("hidden");
     54 
     55 		// Ensure iframe is removed
     56 		section.querySelectorAll("#player_" + stream).forEach(function(x) {
     57 			x.remove();
     58 		});
     59 
     60 		// Reset description text
     61 		var desc_txt = "";
     62 
     63 	}
     64 
     65 	// Insert description text into description field
     66 	section.querySelector("#description_" + stream).innerText = desc_txt;
     67 
     68 	// Mark Loading indicator as done
     69 	tw2html_loading_indicator(stream, status);
     70 
     71 }
     72 
     73 async function tw2html_fetch_description(stream) {
     74 
     75 	// description response
     76 	const desc_resp = await fetch ("/lib/fetch_description.php?stream=" + stream);
     77 
     78 	// extract text of response
     79 	var desc_txt = desc_resp.text();
     80 
     81 	// return result
     82 	return(desc_txt);
     83 
     84 }
     85 
     86 function tw2html_update_preview(stream) {
     87 
     88 		// Construct current time
     89 		var now = new Date();
     90 
     91 		// Get image object
     92 		var prv = document.getElementById("preview_" + stream);
     93 		var img = prv.querySelector("img");
     94 
     95 		// Update preview image
     96 		img.src = "https://static-cdn.jtvnw.net/previews-ttv/live_user_" + stream +
     97 			"-1280x720.jpg" +
     98 			"?t=" + now.getTime(); // Add some index to force reload of image
     99 
    100 		// Ensure preview image is visible
    101 		prv.classList.remove("hidden");
    102 
    103 }
    104 
    105 function tw2html_toggle_player(stream) {
    106 
    107 	// get stream section
    108 	var section = document.getElementById("stream_" + stream);
    109 
    110 	// if player-iframe exists, remove it and unhide preview image
    111 	var player = section.querySelectorAll("#player_" + stream);
    112 	
    113 	if (player.length > 0) {
    114 
    115 		// unhide and update preview image
    116 		tw2html_update_preview(stream);
    117 
    118 		// remove player
    119 		player.forEach(function(x) { x.remove(); });
    120 
    121 		// Hide player container
    122 		section.querySelector(".player_container").classList.add("hidden");
    123 
    124 	} else {
    125 
    126 		// hide preview image
    127 		section.querySelector("#preview_" + stream).classList.add("hidden");
    128 
    129 		// unhide player container
    130 		section.querySelector(".player_container").classList.remove("hidden");
    131 
    132 		// Construct player iframe
    133 	  var player = document.createElement("iframe");
    134   	player.id = "player_" + stream;
    135   	player.classList.add("player");
    136 	  player.allowFullscreen = "true";
    137 	  player.width = "100%";
    138 	  player.height = "100%";
    139 	  player.frameborder = "0";
    140 	  player.scrolling = "no";
    141 	  player.src = "https://player.twitch.tv/?channel=" +
    142 		  stream +
    143 		  "&parent=" +
    144 		  window.location.hostname +
    145 		  "&muted=false&volume=1&quality=auto";
    146 
    147 		// inject player into stream container
    148 		section.querySelector(".player_container").prepend(player);
    149 
    150 		// Focus player
    151 		document.getElementById("player_" + stream).focus();
    152 
    153 		// Scroll to player
    154 		document.location = "#stream_" + stream;
    155 
    156 	}
    157 
    158 }
    159 
    160 function tw2html_toggle_chat(stream) {
    161 
    162 	// get stream section
    163 	var section = document.getElementById("stream_" + stream);
    164 
    165 	// get chat object if it exists
    166 	var chat = section.querySelectorAll("#chat_" + stream);
    167 
    168 	if (chat.length > 0) {
    169 		var chat = chat[0];
    170 	} else {
    171 		var chat = null;
    172 	}
    173 
    174 	if (chat !== null) {
    175 
    176 		chat.remove();
    177 
    178 	} else {
    179 
    180 		// Create chat iframe
    181   var chat = document.createElement("iframe");
    182   chat.id = "chat_" + stream;
    183   chat.width = "100%";
    184   chat.height = "100%";
    185   chat.frameborder = "0";
    186   chat.scrolling = "auto";
    187   chat.src = "https://www.twitch.tv/embed/" +
    188 	  stream +
    189 	  "/chat?parent=" +
    190 	  window.location.hostname;
    191 
    192   // If dark mode is used, apply it to the chat as well
    193   if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
    194 	  chat.src = chat.src + "&darkpopout";
    195   }
    196 
    197   // inject chat into chat container
    198   section.querySelector(".chat_container").prepend(chat);
    199 	}
    200 
    201 }
    202 
    203 function tw2html_loading_indicator(stream, status) {
    204 
    205 	// Get loading indicator object
    206 	var indicator = document.getElementById("loading_indicator_" + stream);
    207 
    208 	// During Process
    209 	if (status == -1) {
    210 
    211 		// Unmark as online
    212 		indicator.classList.remove("online");
    213 
    214 		// Unmark as offline
    215 		indicator.classList.remove("offline");
    216 
    217 	}
    218 
    219 	// Online
    220 	if (status == 1) {
    221 
    222 		// Unmark as offnline
    223 		indicator.classList.remove("offline");
    224 
    225 		// Mark as online
    226 		indicator.classList.add("online");
    227 
    228 	}
    229 
    230 	// Offline
    231 	if (status == 0) {
    232 
    233 		// Unmark as online
    234 		indicator.classList.remove("online");
    235 
    236 		// Mark as offline
    237 		indicator.classList.add("offline");
    238 
    239 	}
    240 
    241 }
    242 
    243 function tw2html_reload() {
    244 
    245 	// Debug output
    246 	console.log("Reloading list of online streams...")
    247 
    248 	// gather list of sections (streams)
    249 	var sections = document.querySelectorAll(".streams");
    250 
    251 	// Loop through each section
    252 	for (i = 0; i < sections.length; i++) {
    253 
    254 		// Gather stream name
    255 		var stream = sections[i].id.replace("stream_", "");
    256 
    257 		// Mark as still processing
    258 		tw2html_loading_indicator(stream, -1)
    259 
    260 		// check online status and untoggle hidden class asynchronously
    261 		tw2html_toggle_hidden(stream);
    262 
    263 	}
    264 
    265 }
    266 
    267 function tw2html_daemon() {
    268 
    269 	// Run reload function initially
    270 	tw2html_reload();
    271 
    272 	// Recall daemon function after 5 minutes
    273 	setTimeout(tw2html_daemon, 60 * 5 * 1000);
    274 }