Bashtube HTML5 Player and Downloader

Добавляет ссылку на видео файл и если браузер поддерживает воспроизведение mp4, то добавляет видеоплеер.

À partir de 2014-09-27. Voir la dernière version.

// ==UserScript==
// @name        Bashtube HTML5 Player and Downloader
// @description Добавляет ссылку на видео файл и если браузер поддерживает воспроизведение mp4, то добавляет видеоплеер.
// @namespace   2k1dmg@userscript
// @match       http://bashtube.ru/video/*
// @version     32
// @author      2k1dmg
// @grant       none
// ==/UserScript==

// 2014-09-27

(function(window) {
	'use strict';
	if (!window || (window && window.self !== window.top)) {
		return;
	}
	var document = window.document;

	var styleSheetLoader = function(canPlay, flash) {
		var cssStyle = document.createElement('style');
		cssStyle.type = 'text/css';
		cssStyle.textContent = '#bt-html5video-panel {\n' +
			'	width: 640px;\n' +
			'	height: 25px;\n' +
			'	padding: 15px 0 10px 0;\n' +
			'}\n' +
			'#bt-html5video-panel > a {\n' +
			'	margin-right: 20px;\n' +
			'	float: right;\n' +
			'}\n' +
			'#bt-html5video-panel > img {\n' +
			'	margin: 0 0 -3px 20px;\n' +
			'}\n';
		if (canPlay)
			cssStyle.textContent += (flash ? '#bt-html5video-panel > button {\n' : '#bt-html5video-panel > sub {\n') +
			'	margin-left: 10px;\n' +
			'	margin-right: 10px;\n' +
			'}\n' +
			'#bt-html5video-panel > span {\n' +
			'	font-size: 90%;\n' +
			'}\n' +
			'#bt-html5video-panel > SPAN.supstr {\n' +
			'    vertical-align: top;  \n' +
			'    font-size: 65%;\n' +
			'}\n' +
			'#bt-html5video-wrapper {\n' +
			'	z-index: 50;\n' +
			'	background: #000;\n' +
			'	top: 0;\n' +
			'	left: 0;\n' +
			'	width: 100%;\n' +
			'	height: 100%;\n' +
			'   opacity: 0;\n' +
			'	transition: opacity 500ms ease-out;\n' +
			'   box-shadow: 0 0 10px 1px #000 inset;\n' +
			'}\n' +
			'#bt-html5video-wrapper.playing {\n' +
			'	opacity: .7;\n' +
			'}\n' +
			'\n' +
			'#bt-html5video-player-container,\n' +
			'#bt-html5video-player {\n' +
			'	position: relative;\n' +
			'	z-index: 100;\n' +
			'}\n' +
			'#bt-html5video-panel button {\n' +
			'   border: 1px solid #aaa;\n' +
			'   background: #eee;\n' +
			'}\n' +
			'#bt-html5video-player-container {\n' +
			'  /*outline: 1px solid green;*/\n' +
			'  display: inline-block;\n' +
			'}\n' +
			'#bt-html5video-player {\n' +
			'  box-shadow: 0 0 5px 1px #000;\n' +
			'}\n' +
			'#bt-html5video-player.playing {\n' +
			'  box-shadow: 0 0 5px 1px #fff;\n' +
			'}\n' +
			'#bt-html5video-player-container > #bt-html5video-player {\n' +
			'  transition: all 300ms ease-in;\n' +
			'}\n' +
			'#bt-html5video-player-container.sizeLarge > #bt-html5video-player {\n' +
			'  width: 960px;\n' +
			'  height: 540px;\n' +
			'}\n' +
			'#bt-html5video-player-controls {\n' +
			'  position: absolute;\n' +
			'  z-index: 150;\n' +
			'  width: 100%;\n' +
			'  height: 28px;\n' +
			'  background-color: rgba(35,31,32,.74);\n' +
			'  opacity: 0;\n' +
			'  color: #ddd;\n' +
			'}\n' +
			'#bt-html5video-player-container:hover #bt-html5video-player-controls {\n' +
			'  opacity: 1;\n' +
			'}    \n' +
			'#bt-html5video-player-size-btn {\n' +
			'  cursor: pointer;\n' +
			'  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAAbCAYAAAAgVez8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzUyQjZBRDEzRTgxMTFFNEE4QzFFRTlDNDAzNkJBNDkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzUyQjZBRDIzRTgxMTFFNEE4QzFFRTlDNDAzNkJBNDkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NTJCNkFDRjNFODExMUU0QThDMUVFOUM0MDM2QkE0OSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NTJCNkFEMDNFODExMUU0QThDMUVFOUM0MDM2QkE0OSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhVpoj0AAACESURBVHja7JgxDoAgDACp8UfOfkffhLM/ceZNOLESMDVQuFshKdc2KanEGN1MLG4yEEYYYYRNsWbOvFKM04pwa/wfiS4Rvj4GPKy1dCI0fuNTeX+32tKJW1OYsYQwwuN+PEaZx9XCngr3OX+LkMyKZ1OKEXrKorDTQhhhhBFGuB9eAQYAbtsR3i9+1uIAAAAASUVORK5CYII=) no-repeat;\n' +
			'  width: 30px;\n' +
			'  height: 27px;\n' +
			'}\n' +
			'#bt-html5video-player-container.sizeLarge #bt-html5video-player-size-btn {\n' +
			'  background-position: -30px 0;\n' +
			'}\n' +
			'.content > .right {\n' +
			'  opacity: 1;\n' +
			'  transition: all 300ms ease-in;\n' +
			'}\n' +
			'.content > .right.sizeLarge {\n' +
			'  position: relative;\n' +
			'  z-index: -1;\n' +
			'  opacity: 0;\n' +
			'}\n' +
			'#bt-html5video-player-controls > * {\n' +
			'  display: inline-block;\n' +
			'  vertical-align: middle;\n' +
			'  margin: 0 2px;\n' +
			'}';
		document.head.appendChild(cssStyle);
	};

	var eventSetter = {
		buttonOnClick: {
			init: function(button, html5ImageColored, html5Image) {
				var onClick = function(event) {
					if (!this.uppod && !this.btHTML5videoPlayer) {
						try {
							this.uppod = document.getElementById('uppod');
							this.btHTML5videoPlayer = document.getElementById('bt-html5video-player');
							var btHTML5videoPanel = document.getElementById('bt-html5video-panel');
							var images = btHTML5videoPanel.getElementsByTagName('img');
							this.image = images[0];
						}
						catch (ex) {
							return;
						};
					}
					this.onclick = function() {
						if (this.uppod.style.display == 'none') {
							this.uppod.style.removeProperty('display');
							this.btHTML5videoPlayer.style.display = 'none';
							this.textContent = 'HTML5';
							this.image.src = html5Image;
							
							this.btHTML5videoPlayer.pause();
							
							this.screenButton.style.display = 'none'; 
						}
						else {
							this.btHTML5videoPlayer.style.removeProperty('display');
							this.uppod.style.display = 'none';
							this.textContent = 'FLASH';
							this.image.src = html5ImageColored;
							
							this.screenButton.style.removeProperty('display');
						}
					};
					return this.onclick();
				};
				button.onclick = onClick;
			}
		},
		linkOnClick: {
			init: function(link) {
				var onClick = function(event) {
					if (event && event.button === 0) {
						event.preventDefault();
						event.stopPropagation();
					}
				};
				link.onclick = onClick;
				link.title = 'Скачивать правой кнопкой мыши!\nИ выбрать: "Сохранить объект как…" или т.п';
			}
		},
		playerOnData: {
			init: function(btHTML5videoPlayer) {
				btHTML5videoPlayer.addEventListener('loadedmetadata', function(e) {
					var width = this.videoWidth,
						height = this.videoHeight;
					var btHTML5videoPanel = document.getElementById('bt-html5video-panel');
					var spans = btHTML5videoPanel.getElementsByTagName('span');
					if (spans[0]) {
						spans[0].textContent = width + 'x';
						spans[1].style.color = 'black';
						spans[1].textContent = height;
						if (height >= 720) {
							spans[2].className = 'supstr'
							spans[2].textContent = ' HD';
						}
					}
				}, false);
			}
		}
	};

	var createLink = function(params) {
		var file = params.file;
		var poster = params.poster;
		var flash = params.flash;

		var videoInfos = document.getElementsByClassName('video-info');
		var videoInfo = videoInfos[0];

		var canPlay = (function() {
			try {
				var v = document.createElement('video');
				return v.canPlayType('video/mp4') !== '';
			}
			catch (ex) {
				return false;
			}
		}());

		var addHTML5video = function() {
			var btHTML5videoPlayer = document.createElement('video');
			var playerParams = [
				['id', 'bt-html5video-player'],
				['width', 640],
				['height', 360],
				['volume', 0.5],
				['controls', 'controls'],
				['poster', poster]
			];
			playerParams.forEach(function(param) {
				btHTML5videoPlayer[param[0]] = param[1];
			});
			btHTML5videoPlayer.innerHTML = '<source src="' + file + '" type="video/mp4">';
			
			var btHTML5videoPlayerContainer = document.createElement('div');
			btHTML5videoPlayerContainer.id = 'bt-html5video-player-container';
			var btHTML5videoPlayerControls = document.createElement('div');
			
			var btHTML5videoPlayerBtn = document.createElement('div');
			btHTML5videoPlayerBtn.id = 'bt-html5video-player-size-btn';
			btHTML5videoPlayerBtn.title = 'Размер видеоплеера';
			btHTML5videoPlayerBtn.onclick = function() {
				if (!this.rights && !this.btHTML5videoPlayer) {
					try {
						var btHTML5videoPlayer = this.btHTML5videoPlayer = document.getElementById('bt-html5video-player');
						var contents = document.getElementsByClassName('content');
						var rights = contents[0].getElementsByClassName('right');
						if (rights[1]) {
							this.rights = rights[1];
						}
					}
					catch (ex) {
						return;
					};
				}
				//if (this.rights.style.display == 'none') {
				if (this.rights.classList.contains('sizeLarge')) {
					//this.rights.style.removeProperty('display');
					this.rights.classList.remove('sizeLarge');
					btHTML5videoPlayerContainer.classList.remove('sizeLarge');
				}
				else {
					//this.rights.style.display = 'none';
					this.rights.classList.add('sizeLarge');
					btHTML5videoPlayerContainer.classList.add('sizeLarge');
				}
			};
			
			var btHTML5videoPlayerControls = document.createElement('div');
			btHTML5videoPlayerControls.id = 'bt-html5video-player-controls';
			btHTML5videoPlayerControls.appendChild(btHTML5videoPlayerBtn);
			
			var btHTML5videoPlayerLoopBox = document.createElement('div');
			//btHTML5videoPlayerLoopBox.style.display = 'inline-block';
			btHTML5videoPlayerLoopBox.title = 'Повторять это видео';
			var btHTML5videoPlayerLoop = document.createElement('input');
			btHTML5videoPlayerLoop.type = 'checkbox';
			btHTML5videoPlayerLoop.name = 'video-loop';
			btHTML5videoPlayerLoop.value = 'false';
			btHTML5videoPlayerLoop.onchange = function() {
				if (this.checked) {
					btHTML5videoPlayer.setAttribute('loop', '');
				}
				else if (btHTML5videoPlayer.loop) {
					btHTML5videoPlayer.removeAttribute('loop');
				}
			};
			
			
			btHTML5videoPlayerLoopBox.appendChild(btHTML5videoPlayerLoop);
			//btHTML5videoPlayerLoopBox.textContent = 'Loop';
			btHTML5videoPlayerLoopBox.insertAdjacentHTML('beforeend', 'Loop');
			
			btHTML5videoPlayerControls.appendChild(btHTML5videoPlayerLoopBox);
			
			btHTML5videoPlayerContainer.appendChild(btHTML5videoPlayerControls);
			btHTML5videoPlayerContainer.appendChild(btHTML5videoPlayer);
			videoInfo.parentNode.insertBefore(btHTML5videoPlayerContainer, videoInfo);

			var btHTML5videoWrapper = document.createElement('div');
			btHTML5videoWrapper.id = 'bt-html5video-wrapper';
			document.body.appendChild(btHTML5videoWrapper);
			
			btHTML5videoPlayer.onplay = function() {
				if (typeof this.updateTimeoutID == 'number') {
					window.clearTimeout(this.updateTimeoutID);
					this.updateTimeoutID = null;
				}
				if (typeof btHTML5videoWrapper.updateTimeoutID == 'number') {
					window.clearTimeout(btHTML5videoWrapper.updateTimeoutID);
					btHTML5videoWrapper.updateTimeoutID = null;
				}
				this.updateTimeoutID = window.setTimeout(function() {
					var btHTML5videoWrapper = document.getElementById('bt-html5video-wrapper');
					btHTML5videoWrapper.classList.add('playing');
					btHTML5videoPlayer.classList.add('playing');
					btHTML5videoWrapper.style.position = 'fixed';
				}, 50);
			};
			
			btHTML5videoPlayer.onpause = function() {
				if (typeof this.updateTimeoutID == 'number') {
					window.clearTimeout(this.updateTimeoutID);
					this.updateTimeoutID = null;
				}
				if (typeof btHTML5videoWrapper.updateTimeoutID == 'number') {
					window.clearTimeout(btHTML5videoWrapper.updateTimeoutID);
					btHTML5videoWrapper.updateTimeoutID = null;
				}
				this.updateTimeoutID = window.setTimeout(function() {
					var btHTML5videoWrapper = document.getElementById('bt-html5video-wrapper');
					btHTML5videoWrapper.classList.remove('playing');
					btHTML5videoPlayer.classList.remove('playing');
					btHTML5videoWrapper.updateTimeoutID = window.setTimeout(function() {
						btHTML5videoWrapper.style.removeProperty('position');
					}, 500);
				}, 50);
			};
			
			btHTML5videoPlayer.onseeking = function() {
				if (this.currentTime == 0)
					return;
				if (typeof this.updateTimeoutID == 'number') {
					window.clearTimeout(this.updateTimeoutID);
					this.updateTimeoutID = null;
				}
			};
			
			btHTML5videoWrapper.onclick = function() {
				btHTML5videoPlayer.pause();
				//btHTML5videoWrapper.className = '';
			};
			
			eventSetter.playerOnData.init(btHTML5videoPlayer);

			var uppod = document.getElementById('uppod');
			uppod.style.display = 'none';

			var flashBtn = btHTML5videoPanel.getElementsByClassName('flash');
			if (flashBtn[0]) {
				eventSetter.buttonOnClick.init(flashBtn[0], html5ImageColored, html5Image);
			}

			var links = btHTML5videoPanel.getElementsByTagName('a');
			if (links[0]) {
				eventSetter.linkOnClick.init(links[0]);
			}
		};
		
		var btHTML5videoPanel = document.createElement('div');
		btHTML5videoPanel.id = 'bt-html5video-panel';

		var html5ImageColored = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAATdJREFUeNpifOqtlsDAwDCfgQwgvfUWIxOQfsBAAWCiQO8BEMECxBdgIvypVQzc/vF4db2tjGX4efkUnM8C9McHYDiAOf++fgbTv+9dZ/gPZaODfwjxDzAXYICvmxYyfNuznpAXLiIbAPKGwa/LJ4FUDgOXcxADs5gMVl2fl01G4bMgOwcG2HTNwBgd/H31FNmABxhe+H3vBjiQsAHh9sUMf18+RRZCMeAgEDv8+/oJJYThcc3NR3w6kNpyk0F83j4GdqgXmMWlGThdAsHsP69wu+ADIpo+AQNQGuxkjDBA8gIw+h+gxwIYvM4LYOCwcAG7AESDDPxxYi/Dj+N7GH5h8R4LNlu+blwIxnjABfQwADlnAZEZC6R5IozDiC4LTNYGoBgBYn8oDQqfDdCY2gBK+sjqAQIMACfPddVHcozkAAAAAElFTkSuQmCC';
		var html5Image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/klEQVR42sWTqw6DMBSGeYQ9wh5hj7BHqeCuFjRiBotFLsEiZrAEiQSNWYImmcN2/ZudpjA6mNqfHNPT851ba/m+z8Iw5EEQ/GSIsSDbts9/AXieV0sAY+xAgKqq+JbSNJ0DIAKUZSkvDcPA+75ftSRJCHA3AvI832xBDP+qAILW4hDlQcgE2JqZALUOMGkcRx3APgBRFEnImlFlBMD2FADlfOsX4N0AKpXWFccxL4pCnjdNowBi/UcFcF33Qo5pmowz0Ido6UI55KCMXdfJIACROcsy2comYM8fwNpnAPQj2rgJx2PHH2hnK1zKcZwTZoLVvl/oE3AE4d8s778Aj+4t+EF6GnYAAAAASUVORK5CYII=';

		if (canPlay) {
			btHTML5videoPanel.innerHTML = '<img src="' + html5ImageColored + '" width="16" height="16" alt="">' +
					(flash ? '<button class="flash">FLASH</button>' : '<sub>HTML5</sub>') +
					'<span></span>' +
					'<span></span>' +
					'<span></span>' +
					'<a href="' + file + '" title="Скачивать правой кнопкой мыши!' +
						'И выбрать: &quot;Сохранить объект как…&quot; или т.п">Скачать</a>';
			addHTML5video();
		}
		else {
			btHTML5videoPanel.innerHTML = '<a href="' + file + '"> Скачать</a>';
		}
		styleSheetLoader(canPlay, flash);
		videoInfo.parentNode.insertBefore(btHTML5videoPanel, videoInfo);
	};

	var addSearchInGoogleBtn = function() {
		var videoPages = document.getElementsByClassName('video-page');
		var videoPage = videoPages[0];
		var videoPageH1 = videoPage.getElementsByTagName('h1');
		//var searchInGoogle = '<button style="margin-left:10px;color: #555; border: 1px solid #aaa;display:inline;" onclick="javascript:window.open("https://www.google.ru/search?q=" + encodeURIComponent(this.parentNode.firstChild.textContent));void 0;">искать в Google</button>';
		var searchInGoogle = document.createElement('button');
		searchInGoogle.setAttribute('style', 'cursor:pointer;display:inline;margin-left:10px;color:#555;background:#eee;border:1px solid #aaa;');
		searchInGoogle.setAttribute('onclick', 'javascript:window.open("https://www.google.ru/search?q="+encodeURIComponent(this.parentNode.firstChild.textContent));void 0;');
		searchInGoogle.textContent = 'искать в Google';

		if (videoPageH1[0]) {
			videoPageH1[0].appendChild(searchInGoogle);
		}
	};
	
	var getParams = function() {
		addSearchInGoogleBtn();
	
		var getScriptContent = function() {
			var lastSibling = uppod.nextSibling;
			var targetContent;
			for (var i = 0; i < 15; i++) {
				if (lastSibling.nodeType === 1 &&
					/.*file:\s'(http:[^']*).*/m.test(lastSibling.textContent)) {
				   targetContent = lastSibling;
				   break;
				}
				lastSibling = lastSibling.nextSibling;
			}
			if (targetContent) {
				return targetContent.textContent;
			}
			else {
				return null;
			}
		};

		var getPageBodyParams = function() {
			var bodyContent = getScriptContent() || document.body.innerHTML;
			var matchBodyContent = bodyContent.match(/.*file:\s'(http:[^']*).*/m);
			var matchBodyContentPoster = bodyContent.match(/.*poster:\s'(http:[^']*).*/m);
			if (matchBodyContent[1]) {
				file = matchBodyContent[1];
				poster = matchBodyContentPoster[1] ? matchBodyContentPoster[1] : '';
				return {'file': file, 'poster': poster, 'flash': false};
			}
		};

		var getUppodParams = function() {
			var matchFlashvars = flashvars.match(/.*file=(http:[^&]*).*/m);
			var matchPoster = flashvars.match(/.*poster=(http:[^&]*).*/m);
			if (matchFlashvars[1]) {
				file = matchFlashvars[1];
				poster = matchPoster[1] ? matchPoster[1] : '';
				return {'file': file, 'poster': poster, 'flash': true};
			}
		};

		var uppod = document.getElementById('uppod');
		var uppodParams = uppod.getElementsByTagName('param');
		var flashvars;
		var file;
		var poster;
		var params;
		if ('flashvars' in uppodParams && uppodParams['flashvars'].value) {
			flashvars = uppodParams['flashvars'].value;
			params = getUppodParams();
		}
		else {
			params = getPageBodyParams();
		}
		if (params) {
			return params;
		}
	};

	var params;
	if (document.readyState === 'complete') {
		params = getParams();
		if (params)
			createLink(params);
	}
	else {
		window.addEventListener('load', function pageLoaded(e) {
			window.removeEventListener('load', pageLoaded, false);
			var params = getParams();
			if (params)
				createLink(params);
		}, false);
	}
})(window);