Stream URL grabber

Adds a button that gives you a .m3u8 file for a stream on Twitch or Hitbox.

От 11.01.2016. Виж последната версия.

// ==UserScript==
// @name Stream URL grabber
// @description Adds a button that gives you a .m3u8 file for a stream on Twitch or Hitbox.
// @include http://www.twitch.tv/*
// @include https://www.twitch.tv/*
// @include http://www.hitbox.tv/*
// @include https://www.hitbox.tv/*
// @include	http://api.twitch.tv/api/channels/*/access_token?grabber
// @include	https://api.twitch.tv/api/channels/*/access_token?grabber
// @namespace https://greasyfork.org/users/3167
// @run-at document-end
// @grant none
// @version 0.0.1.20160111134657
// ==/UserScript==
 	
SERVERS = [ 
	["San Francisco, US", "sfo"],
	["Stockholm, Sweden", "arn"],
	["London, UK", "lhr"],
	["Amsterdam, NL", "ams"],
	["Paris, France", "cdg"],
	["Dallas, US", "dfw"],
	["Frankfurt, Germany", "fra"],
	["Washington, US", "iad"],
	["New York, US", "jfk"],
	["Los Angeles, US", "lax"],
	["Prague, Czech Republic", "prg"],
	["Seattle, US", "sea"],
	["San Jose, US", "sjc"],
	["Chicago, US", "ord"]
];

console.log("grabbing");

var host = window.location.host;

if (host=="api.twitch.tv" || host=="www.api.twitch.tv")
{
	//setTimeout(function(){
		//console.log("loaded:" + GM_getValue("token"));


		//var text = $("body").text();
		var text = document.body.textContent;
		//console.log("text:" + text);

		var json = JSON.parse(text);

		//console.log("json:" + json);

		var user = document.URL.split("api.twitch.tv/api/channels/")[1].split("/")[0];

		var token = json['token'];

		var signature = json['sig'];

		var url = 'http://usher.justin.tv/api/channel/hls/' + user + '.m3u8?allow_source=true&token=' + token + '&sig=' + signature;
		var urle = encodeURI(url);

		//console.log("url:" + url);
		//console.log("urle:" + urle);
		//window.open(url);

		//$("body").html('<a href="' + urle + '">' + urle + '</a>"');
		
		
		var manualserver = false;
		if (manualserver)
		{
			document.body.innerHTML = '<a href="' + urle + '">Default server</a>';
			
			var m3u8name = user;
			loadm3u8(urle, m3u8name);
		}
		else
		{
			document.body.innerHTML = '<a href="' + urle + '">' + urle + '</a>';
			
			//var link = document.createElement("a");
			//link.download = urle;
			//link.href = urle;
			
			createm3u8(urle, user, ["default"], true, true)
			

			//window.location.assign(urle);
			//window.open(urle,"_blank");
			//setTimeout(function(){
			//	link.click();
				//window.close(); 
			//},1000)
		}
		//localStorage.setItem("token", text);
		//GM_setValue("token", text);
	//},100)
}
	
var hook = function()
{
	if (host=="www.twitch.tv")
	{
		var div = document.querySelectorAll('.channel-actions')[0];
		if (div==null) {
			setTimeout(function(){hook();},1000);
			return
		}

		var user = document.URL.split("twitch.tv/")[1].split("/")[0];

		var tokenurl = 'http://api.twitch.tv/api/channels/' + user + '/access_token?grabber';

		//var temp = div.innerHTML;

		//div.innerHTML = temp + '<div class="action button"><a href="' + tokenurl + '" target="_blank">Grab stream link</a></div>';
		//var clickaction = "window.open(" + tokenurl + ", 'newwindow', 'width=50%, height=50%'); return false;";
		var clickaction = "window.open('" + tokenurl + "');";
		//div.innerHTML = temp + '<span class="ember-view"><span class="ember-view button action" onclick="' + clickaction + '">Grab stream link</span></span>';
		
		var newspan = document.createElement("span");
		newspan.innerHTML = '<span class="ember-view button action" onclick="' + clickaction + '" style="cursor:pointer;">Grab stream link</span>';
		div.appendChild(newspan);   
		//
		//clearInterval(grabberhook);
		console.log("Hooking...");
		console.log("Stream link: " + tokenurl);
	}

	if (host=="www.hitbox.tv")
	{
		var div = document.querySelectorAll('.stats')[0];
		if (div==null) {
			setTimeout(function(){hook();},1000);
			return
		}

		var user = document.URL.split("hitbox.tv/")[1].split("/")[0];

		var url = 'http://api.hitbox.tv/player/hls/' + user + '.m3u8';

		//var temp = div.innerHTML;

		var clickaction = "window.open('" + url + "');";
		
		var newspan = document.createElement("span");
		newspan.innerHTML = '<span onclick="' + clickaction + '" style="cursor:pointer;">Grab stream link</span>';
		div.appendChild(newspan);    

		
		//div.innerHTML = temp + '<span><a href="' + url + '" target="_blank">Grab stream link</a></span>';
		//div.innerHTML = temp + '<span onclick="' + clickaction + '">Grab stream link</span>';

		//clearInterval(grabberhook);
		console.log("Hooking...");
		console.log("Stream link: " + url);
	}
}

M3U8CONTENT = "";
function loadm3u8(url, filename)
{
	var client = new XMLHttpRequest();
	client.open('GET', url);
	client.onreadystatechange = function() {
		if (client.readyState==4 && client.status==200)
		{
			//alert(client.responseText);
			M3U8CONTENT = client.responseText;
			//console.log("m3u8:" + M3U8CONTENT);
			document.body.innerHTML = 'Servers:';
			
			var key;
			for (key in SERVERS) {
				var server = SERVERS[key];
				parsem3u8(M3U8CONTENT, filename, server);
			}
		}
	}
	client.send();
}

function parsem3u8(text, filename, server)
{

	//alert(client.responseText);
	var temp = text;
	//console.log("m3u8:" + M3U8CONTENT);

	var oldpart1 = temp.split('NODE="video')[1].split('.')[0];
	var oldpart2 = temp.split('NODE="video' + oldpart1 + '.')[1].split('0')[0];

	//video24.arn01
	var oldserver1 = "video" + oldpart1;
	//video24-1.arn01
	var oldserver2 = oldpart2 + "01";

	var newserver1 = "video" + oldpart1;

	var newserver2 = server[1] + "01";

	console.log(oldserver1 + "." + oldserver2 + " -> " + newserver1 + "." + newserver2);

	if (oldserver2==newserver2)
	{
		createm3u8(temp, filename, server, true, false);
	}
	else
	{
		//temp = temp.replace(oldserver1,newserver1);
		//temp = temp.replace(oldserver2,newserver2);
		temp = temp.split(oldserver1).join(newserver1);
		temp = temp.split(oldserver2).join(newserver2);
		
		createm3u8(temp, filename, server, false, false);
	}

	
}

function createm3u8(text, filename, server, defaultserver, autostart)
{
	if (autostart)
	{
		document.body.innerHTML = 'Link: ';
	}
	var textToWrite = text;
	var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
	var fileNameToSaveAs = filename + "_" + server[1] + '.m3u8';

	var downloadLink = document.createElement("a");
	downloadLink.download = fileNameToSaveAs;
	downloadLink.innerHTML = server[0];
	
	if (defaultserver)
	{
		downloadLink.innerHTML = server[0] + " (default)";
	}
	
	// Firefox requires the link to be added to the DOM
	// before it can be clicked.
	downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
	//downloadLink.onclick = destroyClickedElement;
	//downloadLink.style.display = "none";
	document.body.innerHTML = document.body.innerHTML + '<br>';
	document.body.appendChild(downloadLink);
	
	if (autostart)
	{
		//setTimeout(function(){
			downloadLink.click();
			window.close(); 
		//},1000)	
	}
}

hook();

console.log("Stream grabber loaded on host: " + host);