Rai.tv native video player and direct links

This script allows you to watch and download videos on Rai.tv.

当前为 2015-03-26 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Rai.tv native video player and direct links
// @namespace   http://andrealazzarotto.com
// @description This script allows you to watch and download videos on Rai.tv.
// @include     http://www*.rai.*/dl/RaiTV/programmi/media/*
// @include     http://www*.rai.*/dl/RaiTV/tematiche/*
// @include     http://www*.rai.*/dl/*PublishingBlock-*
// @include     http://www*.rai.*/dl/replaytv/replaytv.html*
// @exclude     http://www*.rai.*/dl/RaiTV/dirette/*
// @include     http://*.rai.it/*
// @include     http://www.rainews.it/dl/rainews/*
// @version     8.7.1
// @require     http://code.jquery.com/jquery-latest.min.js
// @grant       GM_xmlhttpRequest
// @license     GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
// ==/UserScript==

var MP4isOk = document.createElement('video').canPlayType('video/mp4');

function playerElement() {
	var selectors = [
		"div.Player",
		"div#Player",
		"div#idPlayer",
		"embed#Player",
		"div.videoContainer:has(iframe)",
		"div.player-video"
	];
	
	for (var k in selectors) {
		var PL = $(selectors[k]).get(0);
		if(PL)
			return $( PL );
	}
	
	return null;
}

// Return a carefully handcrafted MP4 URL from a "bad" URL
function cutAndSew(url, quality, ending) {
	var r = "_[^_]*" + ending + ".*";
	var reg = new RegExp(r, "");
	var base = "http://creativemedia1.rai.it/podcastmhp";
	var piece = url.replace(/.*podcastmhp/, "")
				.replace(reg, "");
	return base + piece + "_" + quality + ".mp4";
}

function appendMsg(text) {
	$("#direct-link").after("<div id='subcontent'>" + text + "</div>");
	var w = playerElement().width();
	$("#subcontent").css({
		"padding": "5px",
		"color": "white",
		"text-shadow": "0 1px 2px black",
		"background": "rgba(0,0,0,0.4)",
		"float": "left",
		"width": (w*0.9) + "px",
		"margin-left": (w*0.05) + "px"
	});
}

function placeHolder(url, kind, PL) {
	if(!PL) {
		PL = playerElement();
	}
	
	$("#direct-link").remove();
	PL.after("<div id='direct-link' />");
	var wi = PL.width();
	var w = wi*0.6;
	var m = wi*0.2;
	// some styling
	$("#direct-link")
		.css({
			'padding': '5px',
			'margin': '10px 0 10px '+m+'px',
			'width': w+'px',
			'border': '1px solid #888',
			'text-align': 'center',
			'box-shadow': '0px 5px 15px 0px rgba(0, 0, 0, .7)',
			'background-color': '#cfc',
			'float': 'left'
		});
	if ((PL).hasClass("videoContainer")) {
		$("#direct-link")
		.css({
			'margin-left': 'auto',
			'margin-right': 'auto',
			'float': 'none',
			'clear': 'both'
		});
		PL.css('overflow', 'auto');
	}
	// place the link
	$("#direct-link")
		.append('<a href="'+url+'">' + kind + " Direct Link</a>");
	$("#direct-link a")
		.css({
			'font-size': '13px',
			'font-weight': 'normal',
			'color': 'black'
		});
	
	// fix the position of the link
	var parent = $("#direct-link").parent();
	var min = PL.prev().height() + PL.height() + parseInt(PL.css("margin-top")) +
		parseInt(PL.css("margin-bottom")) + $("#direct-link").height();
	if (parent.height() < min) {
		parent.height(min + 32).css("position", "relative")
			.css("clear", "both");
		$("#direct-link").css("position","absolute").css("left", 0)
			.css("bottom", parseInt(parent.css("padding-bottom"))*0.4);
	}
}

function setUP(url, kind, title) {
	if(kind.toLowerCase().indexOf("smooth") != -1 ||
			kind.toLowerCase().indexOf("csm") != -1)
		return;
	
	// fix spaces
	url = url.split(' ').join('%20');

	placeHolder(url, kind);
	// place the video
	var PL = playerElement();
	var w = PL.width();
	var h = PL.height();
	PL.empty();
	var tag = '<embed type="application/x-mplayer2" autoplay="true"';
	if(kind == "MP4" && MP4isOk)
		tag = "<video controls autoplay";
	PL.append(tag + ' id="Player" style="width: ' +
			w + 'px; height: ' + h + 'px"' +
			'src="' + url + '">');
	// kill the flash player, if any
	setTimeout(function() {
		if(unsafeWindow.player) {
			unsafeWindow.player.pause();
		}
		else {
			setTimeout(arguments.callee, 400);
		}
	}, 400);

}

function decide(videoURL, videoURL_MP4, estensioneVideo) {
	if (videoURL_MP4) {
		// handle the relinker server-side
		GM_xmlhttpRequest({
			method: 'GET',
			url: 'http://video.lazza.dk/rai/?r=' + encodeURIComponent(videoURL_MP4),
			onload: function(responseDetails) {
				var r = responseDetails.responseText;
				if (r.length > 0)
					setUP(r, "MP4");
			}
		});
	}
	else if (videoURL) {
		// handle the relinker server-side
		GM_xmlhttpRequest({
			method: 'GET',
			url: 'http://video.lazza.dk/rai/?r=' + encodeURIComponent(videoURL),
			onload: function(responseDetails) {
				var r = responseDetails.responseText;
				if (r.substr(r.length - 4).substr(0,1) == '.')
					estensioneVideo = r.substr(r.length - 3).toUpperCase();
				if(r.toLowerCase().indexOf("mms") === 0)
					setUP(r, "MMS Stream");
				else
					if(r.length > 0)
						setUP(r, estensioneVideo);
			}
		});
	} // end if (videoURL)
}

function parseQuery(hash) {
	var result = {};
	var parts = hash.split("&");
	for(var i = 0; i<parts.length; i++) {
		var pair = parts[i].split("=");
		result[pair[0]] = pair[1];
	}
	return result;
}

function purifyTitle(title) {
	return title.replace(/[^A-Za-z0-9]/gi," ").trim().replace(/\ +/gi,"_");
}

function setUpFromURL(url) {
	// get the original page content
	GM_xmlhttpRequest({
		method: 'GET',
		url: url,
		onload: function(responseDetails) {
			var r = responseDetails.responseText;
			// kill script tags to avoid execution (and errors!)
			r = r.replace(new RegExp('script', 'g'), 'dummy');
			r = $('<div></div>').append(r);
			
			var data = $(r).find("div#silverlightControlHost dummy").text();
			
			// set the correct variables
			var videoURL = data.match(/videoURL = ["'](.*?)["']/)[1];
			var videoURL_MP4 = data.match(/videoURL_MP4 = ["'](.*?)["']/)[1];
			var estensioneVideo = data.match(/estensioneVideo = ["'](.*?)["']/)[1];
			
			decide(videoURL, videoURL_MP4, estensioneVideo);
		}
	});
}

$(document).ready(function(){

	unsafeWindow.refreshByJS = false;
	
	var isReplay = !!$("script[src*='/replaytv.js']").length;
	var isTematiche = window.location.href.indexOf("tematiche") > 0;
	var isPublishingBlock = window.location.href.indexOf("PublishingBlock") > 0;
	var isRubriche = window.location.href.indexOf("rubriche") > 0;
	var isMultiple = (isTematiche || isPublishingBlock || isRubriche);
	
	var frames = $("iframe[src*='/dl/objects/embed.html'], iframe[src*='/dl/ray/']");

	if(!isMultiple && !isReplay &&
		(unsafeWindow.videoURL || unsafeWindow.videoURL_MP4)) {

		var videoURL = $("meta[name=videourl]").attr("content");
		if(!videoURL)
			videoURL = unsafeWindow.videoURL;
		var videoURL_MP4 = $("meta[name=videourl_h264]").attr("content");
		if(!videoURL_MP4)
			videoURL_MP4 = unsafeWindow.videoURL_MP4;
		if(!videoURL_MP4)
			videoURL_MP4 = $("meta[name=videourl_mp4]").attr("content");
		var estensioneVideo = unsafeWindow.estensioneVideo;
		if(estensioneVideo)
			estensioneVideo = estensioneVideo.toUpperCase();
		else
			estensioneVideo = "Unknown";
		if(unsafeWindow.MediaItem.type == 'WMV')
			// avoid bug when estensioneVideo = CSM and MediaItem.type = WMV
			estensioneVideo = "WMV";
		
		decide(videoURL, videoURL_MP4, estensioneVideo);

	}
	
	// end Rai.tv "standard"
	
	else if(frames.length) {
		var url = frames.attr("src");
		url = "http://www.rai.tv" + url.replace(/.*embed.html\?/, "");
		setUpFromURL(url);
	}

	// end iframes
	
	else if(isMultiple && !isReplay) {
		if(unsafeWindow.videoURL) {
			document.videoURL = '';
			setInterval(function() {
				if(!playerElement())
					return;
				document.prevURL = document.videoURL;
				document.videoURL = unsafeWindow.videoURL;
				if(document.videoURL && (document.prevURL != document.videoURL)) {
					decide(document.videoURL);
				}
			}, 400);
		}
		else
			setInterval(function() {
				if(!playerElement())
					return;
				document.HprevId = document.Hid;
				document.Hid = $("div.Player").attr("data-id");
				if(!document.Hid)
					try {
						document.Hid = $("div.player-video iframe").attr("src").split("media/")[1].split(".html")[0];
					}
					catch(e) {}

				// remove video list click events to allow opening of "real" pages
				// if not on "tematiche"
				if(!isTematiche) {
					$(".listaVideo a").unbind("click");
				}
				if(document.Hid && (document.Hid != document.HprevId)) {
					var completeURL = "http://www.rai.tv/dl/RaiTV/" +
						"programmi/media/" + document.Hid + ".html";
					setUpFromURL(completeURL);
				}
			}, 400);
	}
	
	// end Tematiche
	
	else if($("script:contains('draw')").length > 0 ||
			$("div.infoVideo").length > 0) {
		var videoURL = $("script:contains('draw')").text().split("'")[1];
		if(videoURL !== null && videoURL.indexOf("relinker") > 0) {
			GM_xmlhttpRequest({
				method: 'GET',
				url: videoURL,
				headers: {
					'Accept': 'application/atom+xml,application/xml,text/xml'
				},
				onload: function(responseDetails) {
					var r = responseDetails.responseText;
					var doc = $.parseXML(r);
					var $xml = $( doc );
					
					var url = $xml.find("REF").attr("HREF");
					url = url.replace("http://", "mms://");
					
					setUP(url, "MMS Stream");
				}
			});
		}
		else if(videoURL !== null && videoURL.indexOf(".html") > 0) {
			setUpFromURL(videoURL);
		}
		else { // last try
			var PL = playerElement();
			var initParams = PL.find("param[name=initParams]").attr("value");
			if (initParams.indexOf("mediaUri") != -1) {
				var url = initParams.split("mediaUri=")[1].split(",")[0];
				decide(url, null, null); // decide will find the type
			}
		}
	}
	
	// end pages like report.rai.it
	
	else if(isReplay) {
		$(window).bind('hashchange', function(){
			var hash = window.location.hash.slice(1);
			var hashdata = parseQuery(hash);
			
			$("#direct-link + #subcontent").remove();
			$("#direct-link").remove();

			var isvideo = hashdata.v;
			document.TheVideoNow = hashdata.v;
			if(isvideo && document.TheVideoNow != document.TheVideoBefore) {
				var dataURL = "http://video.lazza.dk/rai/?i=" + hashdata.v;

				GM_xmlhttpRequest({
					method: 'GET',
					url: dataURL,
					onload: function(responseDetails) {
						var r = responseDetails.responseText;
						if(r.length > 0)
							setUP(r, "MP4");
					}
				});
				document.TheVideoBefore = document.TheVideoNow;
			}
		});
		$(window).trigger( 'hashchange' );
	}
	
	// end Rai Replay

	// handle RTMP based flash objects on Rai.it
	$("object").not("object object").each(function() {
		var o = $(this);
		var flashvars = o.find("param[name=flashvars]").attr("value");
		if(!flashvars)
			flashvars = o.find("embed").attr("flashvars");
		if(!flashvars)
			flashvars = "";
		var path = flashvars.replace(/.*percorso[^=]*=/gi, "")
				.replace(/&.*/gi, "").replace(/\?.*/gi, "");
		if(path.toLowerCase().indexOf("rtmp")!=-1) {
			var url = path.replace('mp4:','').replace('rtmp','http')
						.replace('.mp4','') + '.mp4';
			placeHolder(url, "MP4", o);
		}
	});
	// end code for flash videos
	
	// handle new pages with "video" tags
	// (maybe the above code will be removed in future releases...)
	var pj;
	try {
		pj = unsafeWindow.projekktor();
	}
	catch (e) {
		pj = false;
	}
	if(pj) {
		var files = pj.media;
		var src = files[files.length - 1].file[0].src;
		var el = $('div.projekktor');
		placeHolder(src, 'MP4', el);
		el.parent().css('background', 'transparent');
	}
	// end new pages

}); // end document.ready