Greasy Fork 支持简体中文。

Video Download Button

This script adds a download button on many video sites.

目前為 2017-01-23 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Video Download Button
// @namespace   VDBMB
// @author      MegaByte
// @description This script adds a download button on many video sites.
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @run-at 		document-idle
// @noframes
// @include     http*://*streamcloud.eu/*
// @include     http*://*powerwatch.pw/*
// @include     http*://*vivo.sx/*
// @include     http*://*shared.sx/*
// @include     http*://*youtube.com/watch?v=*
// @include     http*://*nowvideo.to/video/*
// @include     http*://*nowvideo.sx/video/*
// @include     http*://*ecostream.tv/stream/*.html
// @include     http*://*auroravid.to/video/*
// @version     2.5
// @grant       GM_addStyle
// ==/UserScript==


if(!('includes' in String.prototype)) {
	String.prototype.includes = function(str, startIndex) {
		return -1 !== String.prototype.indexOf.call(this, str, startIndex);
	};
}


this.$ = this.jQuery = jQuery.noConflict(true);

function main() {
	var site = window.location.href || document.URL;

	if(site.includes("streamcloud.eu")) streamcloud();
	else if(site.includes("powerwatch.pw")) powerwatch();
	else if(site.includes("vivo.sx")) vivo();
	else if(site.includes("shared.sx")) shared();
	else if(site.includes("youtube.com")) youtube();
	else if(!!site.match(/nowvideo.((sx)|(to))/)) nowvideo();
	else if(site.includes("ecostream.tv")) ecostream();
	else if(site.includes("auroravid.to")) auroravid();
}

function streamcloud() {
	if($("#player_code").length === 0) return;
	var url = jwplayerSource() || searchInScripts("file:\\s?\"https?:\\/\\/.+?\\.mp4\"", "http", ".mp4");
	if(url !== null) 
		$(".container-fluid ul.nav").prepend("<li>" + button(url) + "</li>");
}

function powerwatch() {
  if($("#vplayer").length === 0) return;
	var url = jwplayerSource() || searchInScripts("file:\\s?\"https?:\\/\\/.+?\\.mp4\"", "http", ".mp4");
	if(url !== null) {
		$("h5.h4-fine").html("<span class='head'>"+$("h5.h4-fine").html()+"</span><span class='down'>" + button(url) + "</span>")
		GM_addStyle("h5.h4-fine { display: flex; } h5.h4-fine .head { flex-grow: 1; } h5.h4-fine .down { flex-grow: 0; }");
	}
}

function vivo() {
	$.fn.extend({
		getStyleObject: function() {
			var dom = this.get(0);
			var style;
			var returns = {};
			if(window.getComputedStyle) {
				var camelize = function(a,b){
					return b.toUpperCase();
				};
				style = window.getComputedStyle(dom, null);
				for(var i = 0, l = style.length; i < l; i++) {
					var prop = style[i];
					var camel = prop.replace(/\-([a-z])/g, camelize);
					var val = style.getPropertyValue(prop);
					returns[camel] = val;
				};
				return returns;
			};
			if(style = dom.currentStyle) {
				for(var prop in style){
					returns[prop] = style[prop];
				};
				return returns;
			};
			return this.css();
		},
		copyCSS: function(source) {
			var styles = $(source).getStyleObject();
			this.css(styles);
		}
	});
	var e = $(".stream-content");
	if(e.length === 0) return;
	var url = e.attr("data-url");
	if(typeof url === "undefined") return;
	var lightBTN = $(".light-switch.btn");
	var downBTN = $("<div class='download'>" + button(url) + "</div>");
	downBTN.copyCSS(lightBTN);
	lightBTN.parent().prepend(downBTN);
	GM_addStyle(".download { margin-right: 15px !important;} .download:hover { color: #fff !important; background-color: #39b3d7 !important; border-color: #269abc !important; }  .download a { text-decoration: none; color: white; }");
}

function shared() {
	var e = $(".stream-content");
	if(e.length === 0) return;
	var url = e.attr("data-url");
	if(typeof url === "undefined") return;
	$(".light-switch").parent().prepend("<div class='download'>" + button(url) + "</div>");
	GM_addStyle(".addthis_toolbox { width: unset !important; }  .download { position: relative; background-color: #FF6550; color: #FFF; float: right; font-size: 13px; font-weight: 700; height: 32px; line-height: 32px; margin: 0 0 0 10px; padding: 0 15px; width: auto; cursor: pointer; -webkit-transition: all .35s ease-in; -moz-transition: all .35s ease-in; -o-transition: all .35s ease-in; transition: all .35s ease-in; opacity: 1; z-index: 300; }  .download a { text-decoration: none; color: white;}");
}

/*function youtube() {
	var TYPE = {'5':{'label':'FLV 240p','type':'flv','quality':'240','3d':false,'audio':true,'video':true},
				'6':{'label':'FLV 270p','type':'flv','quality':'270','3d':false,'audio':true,'video':true},
				'13':{'label':'3GP','type':'3gp','quality':'','3d':false,'audio':true,'video':true},
				'17':{'label':'3GP 144p','type':'3gp','quality':'144','3d':false,'audio':true,'video':true},
				'18':{'label':'MP4 360p','type':'mp4','quality':'360','3d':false,'audio':true,'video':true},
				'22':{'label':'MP4 720p','type':'mp4','quality':'720','3d':false,'audio':true,'video':true},
				'34':{'label':'FLV 360p','type':'flv','quality':'360','3d':false,'audio':true,'video':true},
				'35':{'label':'FLV 480p','type':'flv','quality':'480','3d':false,'audio':true,'video':true},
				'36':{'label':'3GP 240p','type':'3gp','quality':'240','3d':false,'audio':true,'video':true},
				'37':{'label':'MP4 1080p','type':'mp4','quality':'1080','3d':false,'audio':true,'video':true},
				'38':{'label':'MP4 2160p','type':'mp4','quality':'2160','3d':false,'audio':true,'video':true},
				'43':{'label':'WebM 360p','type':'webm','quality':'360','3d':false,'audio':true,'video':true},
				'44':{'label':'WebM 480p','type':'webm','quality':'480','3d':false,'audio':true,'video':true},
				'45':{'label':'WebM 720p','type':'webm','quality':'720','3d':false,'audio':true,'video':true},
				'46':{'label':'WebM 1080p','type':'webm','quality':'1080','3d':false,'audio':true,'video':true},
				'82':{'label':'MP4-3D 360p','type':'mp4','quality':'360','3d':true,'audio':true,'video':true},
				'83':{'label':'MP4-3D 480p','type':'mp4','quality':'480','3d':true,'audio':true,'video':true},
				'84':{'label':'MP4-3D 720p','type':'mp4','quality':'720','3d':true,'audio':true,'video':true},
				'85':{'label':'MP4-3D 1080p','type':'mp4','quality':'1080','3d':true,'audio':true,'video':true},
				'92':{'label':'MP4 240p','type':'mp4','quality':'240','3d':false,'audio':true,'video':true},
				'93':{'label':'MP4 360p','type':'mp4','quality':'360','3d':false,'audio':true,'video':true},
				'94':{'label':'MP4 480p','type':'mp4','quality':'480','3d':false,'audio':true,'video':true},
				'95':{'label':'MP4 720p','type':'mp4','quality':'720','3d':false,'audio':true,'video':true},
				'96':{'label':'MP4 1080p','type':'mp4','quality':'1080','3d':false,'audio':true,'video':true},
				'100':{'label':'WebM-3D 360p','type':'webm','quality':'360','3d':true,'audio':true,'video':true},
				'101':{'label':'WebM-3D 480p','type':'webm','quality':'480','3d':true,'audio':true,'video':true},
				'102':{'label':'WebM-3D 720p','type':'webm','quality':'720','3d':true,'audio':true,'video':true},
				'132':{'label':'MP4 240p','type':'mp4','quality':'240','3d':false,'audio':true,'video':true},
				'133':{'label':'MP4 240p - no audio','type':'mp4','quality':'240','3d':false,'audio':false,'video':true},
				'134':{'label':'MP4 360p - no audio','type':'mp4','quality':'360','3d':false,'audio':false,'video':true},
				'135':{'label':'MP4 480p - no audio','type':'mp4','quality':'480','3d':false,'audio':false,'video':true},
				'136':{'label':'MP4 720p - no audio','type':'mp4','quality':'720','3d':false,'audio':false,'video':true},
				'137':{'label':'MP4 1080p - no audio','type':'mp4','quality':'1080','3d':false,'audio':false,'video':true},
				'138':{'label':'MP4 2160p - no audio','type':'mp4','quality':'2160','3d':false,'audio':false,'video':true},
				'139':{'label':'M4A 48kbps - audio','type':'m4a','quality':'48','3d':false,'audio':true,'video':false},
				'140':{'label':'M4A 128kbps - audio','type':'m4a','quality':'128','3d':false,'audio':true,'video':false},
				'141':{'label':'M4A 256kbps - audio','type':'m4a','quality':'256','3d':false,'audio':true,'video':false},
				'151':{'label':'MP4','type':'mp4','quality':'','3d':false,'audio':true,'video':true},
				'167':{'label':'WebM 360p - no audio','type':'webm','quality':'360','3d':false,'audio':false,'video':true},
				'168':{'label':'WebM 480p - no audio','type':'webm','quality':'480','3d':false,'audio':false,'video':true},
				'169':{'label':'WebM 720p - no audio','type':'webm','quality':'720','3d':false,'audio':false,'video':true},
				'170':{'label':'WebM 1080p - no audio','type':'webm','quality':'1080','3d':false,'audio':false,'video':true},
				'171':{'label':'WebM 128kbps - audio','type':'webm','quality':'128','3d':false,'audio':true,'video':false},
				'172':{'label':'WebM 256kbps - audio','type':'webm','quality':'256','3d':false,'audio':true,'video':false},
				'218':{'label':'WebM 480p - no audio','type':'webm','quality':'480','3d':false,'audio':false,'video':true},
				'219':{'label':'WebM - no audio','type':'webm','quality':'','3d':false,'audio':false,'video':true},
				'242':{'label':'WebM 240p - no audio','type':'webm','quality':'240','3d':false,'audio':false,'video':true},
				'243':{'label':'WebM 360p - no audio','type':'webm','quality':'360','3d':false,'audio':false,'video':true},
				'244':{'label':'WebM 480p - no audio','type':'webm','quality':'480','3d':false,'audio':false,'video':true},
				'245':{'label':'WebM 480p - no audio','type':'webm','quality':'480','3d':false,'audio':false,'video':true},
				'246':{'label':'WebM 720p - no audio','type':'webm','quality':'720','3d':false,'audio':false,'video':true},
				'247':{'label':'WebM 720p - no audio','type':'webm','quality':'720','3d':false,'audio':false,'video':true},
				'248':{'label':'WebM 1080p - no audio','type':'webm','quality':'1080','3d':false,'audio':false,'video':true},
				'264':{'label':'MP4 1440p - no audio','type':'mp4','quality':'1440','3d':false,'audio':false,'video':true},
				'266':{'label':'MP4 2160p - no audio','type':'mp4','quality':'2160','3d':false,'audio':false,'video':true},
				'271':{'label':'WebM 1440p - no audio','type':'webm','quality':'1440','3d':false,'audio':false,'video':true},
				'272':{'label':'WebM 2160p - no audio','type':'webm','quality':'2160','3d':false,'audio':false,'video':true},
				'298':{'label':'MP4 720p60 - no audio','type':'mp4','quality':'720','3d':false,'audio':false,'video':true},
				'299':{'label':'MP4 1080p60 - no audio','type':'mp4','quality':'1080','3d':false,'audio':false,'video':true},
				'302':{'label':'WebM 2160p60 - no audio','type':'webm','quality':'2160','3d':false,'audio':false,'video':true},
				'303':{'label':'WebM 1080p60 - no audio','type':'webm','quality':'1080','3d':false,'audio':false,'video':true},
				'308':{'label':'WebM 1440p60 - no audio','type':'webm','quality':'1440','3d':false,'audio':false,'video':true},
				'313':{'label':'WebM 2160p60 - no audio','type':'webm','quality':'2160','3d':false,'audio':false,'video':true},
				'315':{'label':'WebM 2160p60 - no audio','type':'webm','quality':'2160','3d':false,'audio':false,'video':true}};
	var CUSTOM_ORDER = ['5','18','34','43','35','135','44','22','298','45','37','299','46','264','38','266','139','140','141','*'];
	var FORMAT_ORDER = ['mp4','webm','flv','m4a', '3gp', '*'];
	var FORMAT_RULE = {'flv':'max','mp4':'all','webm':'all','m4a':'none', '3gp':'max'}; //options = all, max, min, none, random;
	var BASE_RULE = {'3d':"all",'audio':'all','video':'all'};
	var SORTBY = 2; //0=custom, 1=quality, 2=type;
  
	var w = gindow();
	if (!w.ytplayer || !w.ytplayer.config || !w.ytplayer.config.args) { console.log("Player Config not found"); return; }
	var config = w.ytplayer.config.args;
	var length = config["length_seconds"];
	var lang = config["host_language"];
	var title = config["title"].replace(/ ([-_]? )?/g, "_");
	var data = config["url_encoded_fmt_stream_map"].split(",");
	var fdata = [];
	for(var dat of data) {
		var attr = dat.split("&");
		var map = {};
		for(var att of attr) {
			var ar = att.split("=");
			var name = ar[0];
			var value = decodeURIComponent(ar[1]);
			map[name] = value;
		}
		map["simple_type"] = TYPE[map["itag"]]["type"];
		map["url"] += "&title="+title;
		fdata.push(map);
	}
	var ffdata = formatLinks(fdata, TYPE, CUSTOM_ORDER, FORMAT_ORDER, FORMAT_RULE, BASE_RULE, SORTBY);
	var links = "";
	for(var f of ffdata) 
		links += "<li><span class='yt-ui-menu-item'><a class='download-link' download='" + title + "." + f["simple_type"] + "' href='" + f["url"] + "'>" + TYPE[f["itag"]]["label"] + "</a></span></a></li>";
	$("#watch8-secondary-actions").prepend("<button title='Download' aria-expanded='false' aria-pressed='false' aria-labelledby='yt-uix-tooltip25-arialabel' role='button' type='button' data-tooltip-text='Download' class='yt-uix-button  yt-uix-button-size-default yt-uix-button-opacity yt-uix-tooltip' id='download-video-button'><span><span class='yt-uix-button-icon-wrapper'><img style='width:20px;height:20px;background-size:20px 20px;background-repeat:no-repeat;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABG0lEQVRYR+2W0Q3CMAxE2wkYAdiEEWADmIxuACMwCmzABpCTEmRSO7YTQX+ChECV43t2nF7GYeHPuLD+0AKwC/DnWMAp/N5qimkBuAfBdRTF/+2/AV6ZYFUxVYuicAfoHegd6B3oHfhZB+ByF+JyV8FkrAB74pqH3DU5L3iGoBURhdVODIQF4EjEkWLmmhYALOQgNIBcHHke4buhxXAAaFnaAhqbQ5QAOHHkwhZ8balkx1ICCiEBWNZ+CivdB7REHIC2ZjZK2oWklDDdB1NSdCd/Js2PqQMpSIKYVcM8kE6QCwDBNRCqOBJrW0CL8kCYxL0A1k6YxWsANAiXeC2ABOEWbwHAWrwxpzgkmA/JtIqnxTOElmPnjlkc4A3FykAhA42AxwAAAABJRU5ErkJggg==);' class='yt-uix-button-icon' src='//s.ytimg.com/yt/img/pixel-vfl3z5WfW.gif'></span><span class='yt-uix-button-content'>Download </span><ul class='yt-uix-button-menu hid' style='min-width: 114px; left: 40px; top: 501px; display: none;'>" + links + "</ul></span></button>");
	$(".download-link").click(function(e) {
		if(typeof GM_download === "undefined") return;
		var url = $(this).attr("href");
		var name = $(this).attr("download");
		e.preventDefault();
		GM_download(url, name);
	});
	GM_addStyle(".download-link { text-decoration: none; color: inherit; } .download-link:hover { text-decoration: none; }");
}
	function formatLinks(DATA, TYPE, CORDER, FORDER, FRULE, BRULE, SORT) {
		for(var rule in BRULE) {
			var list = getKeysOfSubMap(TYPE, DATA.slice(), rule, true);
			switch(BRULE[rule]) {
				case "max": removeAll(DATA, list, getMaxQuality(TYPE, list)); break;
				case "min": removeAll(DATA, list, getMinQuality(TYPE, list)); break;
				case "none": removeAll(DATA, list); break;
			}
		}
	  for(var rule in FRULE) {
			var list = getKeysOfSubMap(TYPE, DATA.slice(), "type", rule);
			switch(FRULE[rule]) {
				case "max": removeAll(DATA, list, getMaxQuality(TYPE, list)); break;
				case "min": removeAll(DATA, list, getMinQuality(TYPE, list)); break;
				case "none": removeAll(DATA, list); break;
			}
		}
		switch(SORT) {
			case 0:
				var obj = {};
				for(var t of CORDER)
					obj[t] = [];
				for(var e of DATA) {
					var t = e["itag"];
					if(!CORDER.includes(t)) t="*";
					obj[t].push(e);
				}
				DATA = [];
				for(var t of CORDER)
					DATA.push.apply(DATA, obj[t]);
			break;
			case 1:
				for(var i in DATA) for(var j in DATA)
					if(TYPE[DATA[j]["itag"]]["quality"] < TYPE[DATA[i]["itag"]]["quality"]) {
						var tmp = DATA[i];
						DATA[i] = DATA[j];
						DATA[j] = tmp;
					}
			break;
			case 2:
				var obj = {};
				for(var t of FORDER)
					obj[t] = [];
				for(var e of DATA) {
					var t = TYPE[e["itag"]]["type"];
					if(!FORDER.includes(t)) t="*";
					obj[t].push(e);
				}
				DATA = [];
				for(var t of FORDER)
					DATA.push.apply(DATA, obj[t]);
			break;
		}
		return DATA;
	}

	function removeAll(target, list, exclude) {
		if(typeof exclude != "undefined") list.splice(exclude, 1);
		var l = [];
		for(var j in list)
			l[j] = list[j]["itag"];
		var i = target.length;
		while(i--)
			if(l.includes(target[i]["itag"])) 
				target.splice(i, 1);
	}

	function getMaxQuality(TYPE, list) {
		var max = null;
		for(var e in list) {
			if(max === null) { max=e; continue; }
			if(TYPE[list[e]["itag"]]["quality"] > max["quality"])
				max = e;
		}
		return max;
	}
	function getMinQuality(TYPE, list) {
		var min = null;
		for(var e in list) {
			if(min === null) { min=e; continue; }
			if(TYPE[list[e]["itag"]]["quality"] < min["quality"])
				min = e;
		}
		return min;
	}
	function getKeysOfSubMap(TYPE, data, key, val) {
		var i = data.length;
		while(i--) {
			if(TYPE[data[i]["itag"]][key] !== val) data.splice(i, 1);
		}
		return data;
	}*/

function nowvideo() {
	if($("#content_player").length === 0) return;
	var elem = $("#content_player > a[href*=premium]");
	var url = $("video source").attr("src");
	var title = $($(".video_details h4").get(1)).html();
	
	Downloader(elem, "click", url, title, true);
}

function ecostream() {
	if($("#video").length === 0) return;
	var file = jwplayerSource();
	if(file === null) return;
	$(".downline").append("<br />" + button(file));
	Downloader($("download-link"), "click", file, "video.mp4", true);
	GM_addStyle(".download-link { color: #E3E3E3; text-decoration: none; }");
}

function auroravid() {
	if($("#videoPlayer").length === 0) return;
	cloudplayerSource(function(url, title) {
		title = title.replace("%26asdasdas", "") + ".flv";
		var download = [$("#content_block a.btn[href*=premium]"), 
						$("#videoPlayer param[name=flashvars]")];
		Downloader(download[0], "click", url, title, true);
		download[1].attr("value", download[1].attr("value").replace(/premiumLink=.*?(&|$)/g, "premiumLink="+url+"&"));
	});
}


main();

	function jwplayerSource() {
		var w = gindow();
		if(!w.jwplayer || !w.jwplayer().config) return null;
		var config = w.jwplayer().config;
		
		var file = [];
		if(config.file) 
			file.push(config.file);
		if(config.sources) 
			for(var s of config.sources) 
				file.push(s.file);
		
		if(file.length === 0) return null;
		if (typeof location.origin === 'undefined')
			location.origin = location.protocol + '//' + location.host;
		for(var i in file) 
			if(!file[i].match(/https?:\/\//))
				file[i] = location.origin + file[i];
		return file.length === 1 ? file[0] : file;
	}
	
	function cloudplayerSource(callback) {
		var w = gindow();
		var args = w.flashvars;
		if(typeof args == "undefined" || args === null) {
			args = {};
			var data = $("#videoPlayer param[name=flashvars]").attr("value").split("&");
			for(var d of data) {
				var tmp = d.split("=");
				args[tmp[0]] = tmp[1];
			}
		}
		var file = args["file"];
		var key = args["filekey"];
		var domain = args["domain"];
		var data_url = domain + "/api/player.api.php?file=" + file + "&key=" + key;
		console.log(data_url);
		$.get(data_url, function(data) {
			var vars = {};
			var attr = data.split("&");
			for(var a of attr) {
				var tmp = a.split("=");
				vars[tmp[0]] = tmp[1];
			}
			var url = vars["url"];
			var title = vars["title"];
			callback(url, title);
		});
	}

	function Downloader(elem, trigger, url, name, fallbackAttr) {
		if(isEmpty(elem) || isEmpty(trigger) || isEmpty(url)) return;
		if(isEmpty(name)) name = "video.mp4";
		elem.on(trigger, function(e) {
			if(typeof GM_download === "undefined") return;
			e.preventDefault();
			GM_download(url, name);
		});
		if(fallbackAttr) {
			elem.attr("href", url);
			elem.attr("download", name);
		}
	}
	
	function isEmpty(target, val) {
		return typeof target == "undefined" || target == null || target === "";
	}

	function gindow() {
		return (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window;
	}

	function searchInScripts(patt, start, end) {
		var url = null;
		$("body script").each(function() {
			var regex = new RegExp(patt);
			var out = regex.exec($(this).html());
			if(typeof out !== "undefined" && out !== "" && out !== null) {
				if(typeof out !== "string") out = out[0];
				var s = out.indexOf(start);
				var e = out.lastIndexOf(end);
				if( s!==-1 && e!==-1 ) url = out.substring(s, e);
				return false;
			}
		});
		return url;
	}
	 
	function button(url) {
		return "<a href='" + url + "' download class='download-link' target='_blank'>Download</a>";
	}