Greasy Fork is available in English.

Extract DownloadURL

mp4もしくはm3u8の動画URLを取得します。

Version au 06/11/2016. Voir la dernière version.

// ==UserScript==
// @name           Extract DownloadURL
// @id             ExtractDownloadURL
// @version        0.1.1.20161106
// @description    mp4もしくはm3u8の動画URLを取得します。
// @namespace      https://greasyfork.org/users/2671
// @include        *
// @grant          GM_addStyle
// @grant          GM_xmlhttpRequest
// @noframes
// @run-at         document-end
// ==/UserScript==
var rules = [
{
	reg:/tver\.jp\/\w+\/f?\d+\/?$/
	,title:"div.program.pc>h1"
	,date:"div.program.pc>p>span.day"
}
,{
	reg:/video\.tv-tokyo\.co\.jp\/.+\/?/
	,title:"h1.programTitle"
	,date:"p.date"
}
,{
	reg:/cu\.ntv\.co\.jp\/.+\/?/
	,date:"h1>span.date"
}
];
var addCSSPrefix = function (selector, property, flag) {
	var prefix = ["-moz-", "-webkit-", "-o-", "-ms-"];
		var css = prefix.map(function (value) {
			return (flag=="selector") ? value + selector + ":" + property + ";" : selector + ":" + value + property + ";"
		}).join(" ");
	return "{" + css + "}";
};
var css = {};
css.panel = "div#download_panel";
css.container = css.panel + ">div";
css.topcontent = "div#download_panel_topcontent";
css.bottomcontent = "div#download_panel_bottomcontent";
css.m3u8btn = css.topcontent + ">div.download_panel_bg_m3u8";
css.mp4btn = css.topcontent + ">div.download_panel_bg_mp4";
css.list = "div.download_panel_list";
css.m3u8list = css.bottomcontent + ">div.download_panel_bg_m3u8";
css.mp4list = css.bottomcontent + ">div.download_panel_bg_mp4";
GM_addStyle(
	"div.download_panel_bg_m3u8 {background-color:rgba(224 , 255, 255, 0.5);}" 
	+ "div.download_panel_bg_mp4 {background-color:rgba(255, 192, 203, 0.5);}" 
	+ "div.download_panel_border {border-style:solid; border-width:1px; border-color:rgb(191, 191, 191); border-radius:10px;}" 
	+ "div.download_panel_btn {position:relative; width:50px; height:50px; display:table-cell; color:black; font-size:large; text-align:center; vertical-align:middle; cursor:pointer;}" 
	+ "div.download_panel_space " + addCSSPrefix("box-flex", "1.0", "selector")
	+ css.list + " {padding:10px 30px; white-space:nowrap; overflow-x:auto; overflow-y:auto; display:none; max-width:" + window.innerWidth*0.7 + "px; min-height:50px; max-height:" + window.innerHeight*0.9 + "px;}" 
	+ css.panel + ":hover " + css.list + " {display:block;}"
	+ css.panel + " {position:fixed; top:10px; right:10px; z-index:100000;}"
	+ css.container + " " + addCSSPrefix("display", "box", "property")
	+ css.container + " " + addCSSPrefix("box-orient", "vertical", "selector")
	+ css.topcontent + " " + addCSSPrefix("display", "box", "property")
	+ css.topcontent + " " + addCSSPrefix("box-orient", "horizontal", "selector")
	+ css.list + ">div>* {color:black;}"
	+ css.list + ">div>a {text-decoration:none;}"
	+ "div.download_panel_addm3u8>a {color:orange;}"
);
var createNode = function (tagName, text, attrObj, node) {
	var tag = document.createElement(tagName);
	if (text) tag.textContent = text;
	attrObj = attrObj || {};
	for (var i in attrObj) {
		tag.setAttribute(i, attrObj[i]);
	};
	return (node) ? node.appendChild(tag) : tag;
};
var extractUrl = function () {
	var list = document.documentElement.innerHTML.replace(/&quot;|%22/g, "\"").replace(/&apos;|%27/g, "'").match(/http[^"'<>]+\.(mp4|m3u8)[^"'<>]*/gm);
	if (list==null) return null;
	var obj = {mp4:[], m3u8:[]};
	var rule = rules.find(function (obj) {return obj.reg.test(location.href)});
	obj.title = document.querySelector((rule && rule.title) ? rule.title : "head>title").textContent;
	list = Array.from(list).map(function (url) {
		var cnt = 0;
		while (url.indexOf("%")>-1 && cnt<5) {
			url = decodeURIComponent(url);
			cnt++;
		};
		url = url.replace(/\\u002F/g, "/").replace(/\\/g, "").replace(/&amp;/g, "&");
		return url;
	}).filter(function (url) {return /^https?:\/\/[0-9a-zA-Z\/\-_.\!~\'\(\):]+$/.test(url.replace(/\?.*$/, ""))});
	if (list.length==0) return null;
	Array.from(new Set(list)).forEach(function (url) {
		if (url.indexOf("m3u8")>-1) {
			obj.m3u8.push(url);
		} else {
			obj.mp4.push(url);
		};
	});
	return obj;
};
var createPanel = function () {
	var panel = createNode("div", null, {"id":"download_panel"});
	var container = createNode("div", null, null, panel);
	var topcontent = createNode("div", null, {"id":"download_panel_topcontent"}, container);
	createNode("div", null, {"class":"download_panel_space"}, topcontent);
	createNode("div", null, {"class":"download_panel_btn download_panel_border download_panel_bg_m3u8"}, topcontent);
	createNode("div", null, {"class":"download_panel_btn download_panel_border download_panel_bg_mp4"}, topcontent);
	var bottomcontent = createNode("div", null, {"id":"download_panel_bottomcontent"}, container);
	createNode("div", null, {"class":"download_panel_list download_panel_border download_panel_bg_m3u8"}, bottomcontent);
	createNode("div", null, {"class":"download_panel_list download_panel_border download_panel_bg_mp4"}, bottomcontent);
	document.getElementsByTagName("body")[0].appendChild(panel);
};
var updatePanel = function (list) {
	if (!list) return null;
	if (!list.m3u8) list.m3u8 = [];
	if (!list.mp4) list.mp4 = [];
	if (!document.getElementById("download_panel")) createPanel();
	var m3u8list = document.querySelector(css.m3u8list);
	var mp4list = document.querySelector(css.mp4list);
	var m3u8btn = document.querySelector(css.m3u8btn);
	var mp4btn = document.querySelector(css.mp4btn);
	m3u8btn.textContent = +m3u8btn.textContent + +list.m3u8.length;
	mp4btn.textContent = +mp4btn.textContent + +list.mp4.length;
	list.m3u8.forEach(function (url) {
		var div = createNode("div", null, null, m3u8list);
		createNode("a", list.title, {"href":url}, div);
	});
	list.mp4.forEach(function (url) {
		var div = createNode("div", null, null, mp4list);
		if (url.match(/\D(\d{3,4}[x]\d{3,4})\D/)!=null) createNode("span", RegExp.$1, {"class":"reso", "style":"width:100px;display:inline-block;"}, div);
		createNode("a", list.title, {"href":url}, div);
	});
};
var createBrightComURL = function (node) {
	var target = node.querySelector("*[data-account][data-video-id]");
	if (target==null) return null;
	var pubId = target.getAttribute("data-account");
	var videoId = target.getAttribute("data-video-id");
	if (!/^\d+$/.test(pubId) || !/^\d+$/.test(videoId) || !document.querySelector("video")) return null;
	var rule = rules.find(function (obj) {return obj.reg.test(location.href)});
	var ary = [];
	ary.push((rule && rule.title) ? rule.title : "head>title");
	if (rule && rule.date) ary.push(rule.date);
	return {title:ary.map(function (css) {return document.querySelector(css).textContent}).join(""), m3u8:["http://c.brightcove.com/services/mobile/streaming/index/master.m3u8?pubId=" + pubId + "&videoId=" + videoId]}
};
(function () {
	updatePanel(extractUrl());
	var obj = createBrightComURL(document);
	updatePanel(obj);
	if (obj) return null;
	console.log("Extract DownloadURL MutationObserver開始");
	var mo = new MutationObserver(function (mutations) {
		mutations.some(function (mutation) {
			var node = mutation.target;
			var obj = createBrightComURL(node);
			if (obj) {
				mo.disconnect();
				console.log("Extract DownloadURL MutationObserver切断");
				updatePanel(obj);
				return true
			} else {
				return false;
			}
		});
	});
	mo.observe(document.getElementsByTagName("body")[0], {childList:true, subtree:true, attributes:true});
})();