Greasy Fork

Greasy Fork is available in English.

Download Sibnet Video as MP4

Ссылка на видео в правом нижнем углу плеера, правильные названия видео при скачивании

当前为 2017-10-10 提交的版本,查看 最新版本

// ==UserScript==
// @name        Download Sibnet Video as MP4
// @namespace   http://video.sibnet.ru
// @description Ссылка на видео в правом нижнем углу плеера, правильные названия видео при скачивании
// @include     *://video.sibnet.ru/*
// @version     1.3.2
// @author      Iron_man
// @grant       GM_xmlhttpRequest
// @run-at      document-start
// ==/UserScript==

window.addEventListener('message', recieveMessage, false );
document.addEventListener('DOMContentLoaded', start, false );

var RANDOM = '1669048';// Math.round(Math.random() * 1000000 + 1000000);
var postMessage = true;
var clickCancel = true;
var addVideoId = true;// добавить видео id в название файла
function start()
{
	removeAds();
	if( clickCancel )
		setCancelPostvideo();
	var pladform = detectPladformIFrames();
	if( pladform )
	{
		console.log('embeded video from pladform.ru');
		return;
	}
	var video_path = getVideoPath();// get video path name '/v/{numbers}/{videoid}.mpd' from current html source page
	console.log("video path: " + video_path);
	if( video_path )
	{
		GM_xmlhttpRequest({
			url: video_path,
			method: 'HEAD',
			onload: makeVideoLink,
		});
	}
	newCssClasses();
}
function getVideoPath()
{
	var video, source_str, pos, end;
	video = document.getElementById('video');
	if( video )
		source_str = video.innerHTML;
	else
		source_str = document.body.innerHTML;
	pos = source_str.indexOf( "player.src([{src: \"" );
	if( pos == -1 )
		return null;
	pos = source_str.indexOf("/v/", pos);
	end = source_str.indexOf(".mpd", pos);
	if( end == -1 )
		return null;
	return source_str.substring(pos, end+4);
}
function makeVideoLink( xhr )
{
	var video_link = xhr.finalUrl.replace('/manifest.mpd', '.mp4');// get downloadable video link
	console.log("video file: ", video_link);
	if( !video_link )
	{
		console.error("[makeVideoLink] can't find video source link");
		return;
	}
	var stat = insertLink( video_link );// try to insert the link into 'video_size' element of html source page
	if( stat !== 0 )// if failed to insert the link then 
	{
		if( window.parent !== window.self && postMessage )// if not in parent window then post video_link to parent
			window.parent.postMessage( video_link + '&id=' + this.url.match(/\d+\.mpd/)[0].slice(0,-4), '*');
		confirmDownloadFile( video_link );
	}
}
function insertLink( source_link, size_mb ) // insert hyper reference into video_size element  
{
	var video_size = document.getElementsByClassName('video_size')[0];
	if( !video_size )
		return 1;
	size_mb = size_mb || video_size.innerHTML;
	video_size.innerHTML = '' +
	'<a id="video_file_' + RANDOM + '" class="video_file_active" href="' + source_link + '" ' +
		'title="Скачать">' + size_mb + '</a>';
	var video_file = document.getElementById('video_file_' + RANDOM);
	video_file.addEventListener('click', handleDownloadFileEvent, false);
	return 0;
}
function handleDownloadFileEvent(event)
{
	if( event.ctrlKey )
		return;
	event.preventDefault();
	var t = event.target;
	if( t.classList.contains('video_file_active') )
	{
		t.classList.remove('video_file_active');
		downloadFile( getFileName(), t.href );
	}
}
function getFileName()
{
	var fileName = document.querySelector('td.video_name > h1'),
		videoIdStr = (addVideoId ? " " + getVideoId() : "");
	if( fileName )
		return fileName.innerHTML + videoIdStr + ".mp4";
	fileName = document.querySelector('meta[property="og:title"]');
	if( fileName )
		return fileName.getAttribute('content') + videoIdStr + ".mp4";
	return "video_name_" + getVideoId() + ".mp4";
}
function getVideoId()
{
	var href = window.location.href;
	return href.match(/video(id\=|)(\d+)/)[2];
}
function confirmDownloadFile( source )
{
	GM_xmlhttpRequest({
		url: source,
		method: 'HEAD',
		onload: function(xhr){
			if( xhr.status !== 200 )
			{
				console.error("xhr.status: ", xhr.status, xhr.statusText );
				console.error("url: " + this.url);
				console.error("method: " + this.method);
				return;
			}
			var fileSize = getContentLength( xhr.responseHeaders ),
				fileName = getFileName();
			showConfirmWindow( fileName, fileSize, this.url );
		}
	});
}
function showConfirmWindow( fileName, fileSize, fileUrl )
{
	var confirmWnd = document.querySelector('#confirm_downlaod_window_' + RANDOM);
	if( !confirmWnd )
	{
		confirmWnd = document.createElement('div');
		confirmWnd.setAttribute('id', 'confirm_downlaod_window_' + RANDOM);
		confirmWnd.setAttribute('class', 'confirm_download_window');
		var body = document.body || document.getElementsByTagName('body')[0];
		body.appendChild(confirmWnd);
		var html = '' +
		'<div id="confirm-filename"></div>' +
		'<div id="confirm-filesize"></div>' +
		'<div id="confirm-bottom">' +
			'<button id="confirm-download-button-true" class="confirm-button">Скачать</button>' +
			'<button id="open-video-source-file" class="confirm-button">Ссылка</button>' +
			'<button id="confirm-download-button-false" class="confirm-button">Отмена</button>' +
		'</div>' +
		'';
		confirmWnd.innerHTML = html;
		confirmWnd.addEventListener('click', handleConfirmEvent, false);
	}
	var fileNameDiv = confirmWnd.querySelector('#confirm-filename'),
		fileSizeDiv = confirmWnd.querySelector('#confirm-filesize'),
		fileSourceBtn = confirmWnd.querySelector('#open-video-source-file');
	fileNameDiv.innerHTML = 'Имя файла: ' + shortenFileName(fileName);
	fileNameDiv.setAttribute('title', fileName);
	fileSizeDiv.innerHTML = 'Размер файла: ' + bytesToMB(fileSize, 1) + ' Mb';
	fileSourceBtn.setAttribute('title', fileUrl );
	confirmWnd.setAttribute('file-name', fileName);
	confirmWnd.setAttribute('file-size', fileSize);
	confirmWnd.setAttribute('file-source', fileUrl );
	confirmWnd.style.display = '';
}
function shortenFileName( fileName )
{
	this.maxLen = this.maxLen || 25;
	if( fileName.length > this.maxLen )
	{
		var nameEnd = (addVideoId ? fileName.match(/\d+\.mp4/)[0] : fileName.slice(-11));
		fileName = fileName.slice(0, (this.maxLen - nameEnd.length) );
		fileName += '...' + nameEnd;
	}
	return fileName;
}
function handleConfirmEvent(event)
{
	var t = event.target;
	if( t.tagName !== 'BUTTON' )
		return;
	if( t.id === 'confirm-download-button-false' )
		this.style.display = 'none';
	else if( t.id === 'confirm-download-button-true' )
	{
		var fileName = this.getAttribute('file-name'),
			fileUrl = this.getAttribute('file-source');
		this.style.display = 'none';
		downloadFile( fileName, fileUrl );
	}
	else if( t.id === 'open-video-source-file' )
		window.open( this.getAttribute('file-source') );
}
function getContentLength( headersStr )
{
	var headers = headersStr.split('\r\n');
	for( var i = 0, h; i < headers.length; ++i )
	{
		h = headers[i];
		if( h.indexOf('Content-Length') != -1 )
			return parseInt(h.match(/\d+/)[0], 10);
	}
	return 0;
}
function downloadFile( name, source )
{
	GM_xmlhttpRequest({
		url: source,
		method: 'GET',
		responseType: 'blob',
		onload: function(xhr){
			if( xhr.status !== 200 )
			{
				console.error("xhr.status: ", xhr.status);
				console.error("url: ", this.url);
				return;
			}
			var wURL = window.webkitURL || window.URL,
				resource = wURL.createObjectURL(xhr.response),
				body = document.body || document.getElementsByTagName('body')[0],
				a = document.createElement('a');
			a.setAttribute('download', name);
			a.href = resource;
			body.appendChild(a);
			a.click();
			a.parentNode.removeChild(a);
			var video_file = document.querySelector('#video_file_' + RANDOM);
			if( video_file )
				video_file.classList.add('video_file_active');
			wURL.revokeObjectURL(resource);
		},
		onprogress: function(xhr){
			if( !xhr.lengthComputable )
				return;
			showDownloadWindow(xhr.total, xhr.loaded);
		}
	});
}
function showDownloadWindow(total, loaded)
{
	var dlWnd = document.querySelector('#download_window_' + RANDOM);
	if( !dlWnd )
	{
		dlWnd = document.createElement('div');
		dlWnd.setAttribute('id', 'download_window_' + RANDOM);
		dlWnd.setAttribute('class', 'video_download_window');
		dlWnd = (document.body || document.getElementsByTagName('body')[0]).appendChild(dlWnd);
	}
	dlWnd.style.display = '';
	var html = bytesToMB(loaded, 1) + ' Mb / ' + bytesToMB(total, 1) + ' Mb' +
		' (' + (loaded/total*100).toPrecision(3) + '%)';
	dlWnd.innerHTML = html;
	if( total === loaded )
	{
		setTimeout(function(){
			dlWnd.style.display = 'none';
		}, 3000 );
	}
}
function bytesToMB( bytes, precision )
{
	return (bytes/(1024*1024)).toFixed(precision || 0);
}
function addCssClass( cssClass )
{
	var head = document.head || document.getElementsByTagName('head')[0],
		style = document.createElement('style');
	style.type = 'text/css';
	if( style.styleSheets )
		style.styleSheets.cssText = cssClass;
	else
		style.appendChild(document.createTextNode(cssClass));
	head.appendChild(style);
}
function newCssClasses()
{
	addCssClass(`
		.confirm-button {
			background-color: #16a085;
			color: #c7c7c7;
			font-size: 1.0em;
			border-radius: 5px;
			font-family: sans-serif;
			border: 2px solid #c7c7c7;
			cursor: pointer;
			margin: 0.4% 1% 0.4% 1%;
			test-align: center;
		}
		.confirm-button:hover {
			background-color: #058f74;
			border-color: white;
			color: white;
		}
		#confirm-bottom {
			text-align: center;
		}
		.confirm_download_window,
		.video_download_window {
			position: fixed;
			bottom: 30px;
			right: 30px;
			z-index: 9999;
			background-color: #16a085;
			color: white;
			box-shadow: 5px 5px 5px #555555;
			font-size: 1.2em;
			font-family: sans-serif;
			border-radius: 5px;
			padding: 2px 10px 2px 10px;
			display:;
			cursor: default;
		}
	`);
}
function removeAds()
{
	var tbody = document.querySelector('.main tbody');
	if( tbody && tbody.children && tbody.children[0] )
		tbody.children[0].innerHTML = '<td style="height:0px"></td>';
}
function setCancelPostvideo()
{
	var player_container = document.getElementById('player_container');
	if( player_container )
	{
		player_container.addEventListener('ended', function(event){
			var postvideo_cancel = document.getElementsByClassName('vjs-postvideo-cancel')[0];
			if( postvideo_cancel )
				setTimeout( function(){postvideo_cancel.click();}, 1000 );
		}, true );
	}
}
function detectPladformIFrames()
{
	var iFrames = document.getElementsByTagName('iframe'), count = 0;
	for( var i = 0; i < iFrames.length; ++i )
	{
		if( iFrames[i].src.indexOf('pladform.ru') != -1 )
		{
			iFrames[i].setAttribute('name', 'pladform' + i);
			iFrames[i].setAttribute('id', 'pladform' + i);
			++count;
		}
	}
	return count;
}
function recieveMessage(event)
{
	if( event.origin.indexOf('out.pladform.ru') != -1 )
	{
		var stat = insertLink( event.data.url, '- Mb' );// try to insert link to video_size
		if( stat !== 0 )// if failed then
		{
			if( window.parent !== window.self && postMessage )// if not in parent window then
				window.parent.postMessage(event.data.url, '*');// post message to parent
			confirmDownloadFile( event.data.url );
		}
	}else{
		//console.info('[recieveMessage] message from ' + event.origin + ' is ignored');
	}
}