futaba WebM inline player

WebMをページ内で再生しちゃう

当前为 2016-01-02 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        futaba WebM inline player
// @namespace   https://github.com/himuro-majika
// @description WebMをページ内で再生しちゃう
// @author      himuro_majika
// @include     http://may.2chan.net/webm/*
// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
// @version     1.3
// @grant       none
// @run-at      document-idle
// @license     MIT
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAPUExURYv4i2PQYy2aLUe0R////zorx9oAAAAFdFJOU/////8A+7YOUwAAAElJREFUeNqUj1EOwDAIQoHn/c88bX+2fq0kRsAoUXVAfwzCttWsDWzw0kNVWd2tZ5K9gqmMZB8libt4pSg6YlO3RnTzyxePAAMAzqMDgTX8hYYAAAAASUVORK5CYII=
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);

(function ($) {
	/**
	 * 設定
	 */
	// フルサイズプレーヤーを有効にする(4chanライクな表示)
	var USE_FULLPLAYER = true;
	// ループ再生を有効にする
	var USE_LOOP = true;
	// 自動再生を有効にする(ミニサイズプレーヤー使用時)
	var USE_AUTOPLAY = false;
	// コントロールを表示する(ミニサイズプレーヤー使用時)
	var USE_CONTROLS = true;
	// ミュート状態で再生する
	var USE_MUTED = false;
	// フルサイズプレーヤーに時間を表示する
	var USE_TIME_DISPLAY = true;
	
	
	init();
	function init() {
		var AKAHUKU = false, FUTAKURO = false;
		// 赤福が有効か
		if ($("#akahuku_thumbnail").length) { AKAHUKU = true; }
		// ふたクロが有効か
		if ($("#master").length) { FUTAKURO = true; }
		getImgNodeThread();
		getImgNodeRes();
		if (AKAHUKU || FUTAKURO) {
			observeInserted();
		}
		// スレ画
		function getImgNodeThread() {
			var $sure_a = $("body > form > a > img");
			if (FUTAKURO) { // ふたクロ
				$sure_a = $("#master > a > img");
			}
			$sure_a.each(function() {
				replaceNode($(this));
			});
		}
		// レス画像
		function getImgNodeRes() {
			var $res_a = $(".rtd > a > img");
			$res_a.each(function() {
				replaceNode($(this));
			});
		}
		// 続きを読むで挿入される要素を監視
		function observeInserted() {
			var target = $("html > body > form[action]:not([enctype])").get(0);
			var observer = new MutationObserver(function(mutations) {
				mutations.forEach(function(mutation) {
					var $nodes = $(mutation.addedNodes);
					replaceNodeInserted($nodes);
				});
			});
			observer.observe(target, { childList: true });
		}
		// 挿入されたレス
		function replaceNodeInserted($nodes) {
			var $res_inserted = $nodes.find("td > a > img");
			if (AKAHUKU) {
				if ($res_inserted.length) {
					replaceNode($res_inserted);
				}
			} else if (FUTAKURO) {
				$res_inserted.each(function(){
					replaceNode($(this));
				});
			}
		}
		// ノードの書き換え
		function replaceNode(node) {
			var href = node.parent().attr("href");
			if (!href.match(/\.webm$/)) {
				// 拡張子.webm以外
				return;
			}
			var width = node.attr("width");
			var height = node.attr("height");
			var timer;
			// マウスオーバーで読み込み
			node.hover(function(){
				if (USE_FULLPLAYER) {
					timer = setTimeout(function(){
						showFullPlayer();
					}, 300);
				} else {
					addMiniPlayer();
				}
			},function(){
				if (USE_FULLPLAYER) {
					clearTimeout(timer);
					hideFullPlayer();
				}
			});
			// ミニプレイヤー
			function addMiniPlayer() {
				var $videoContainer = $("<div>", {
					class: "GM_fwip_container_mini",
					css: {
						"margin": "0 20px",
						"float": "left",
						"clear": "left",
					}
				}).append(
					$("<video>", {
						class: "GM_fwip_player",
						css: {
							"width": width,
							"height": height,
						},
					}).prop({
						controls: USE_CONTROLS,
						autoplay: USE_AUTOPLAY,
						loop: USE_LOOP,
						muted: USE_MUTED,
					}).append(
						$("<source>", {
							src: href,
							type: "video/webm",
						})
					)
				);
				// サムネイル画像を隠す
				node.hide();
				node.parent().before($videoContainer);
			}
			// フルプレイヤーを表示する
			function showFullPlayer() {
				hideFullPlayer();
				// サムネ右端のオフセット
				var offset = parseInt(node.offset().left) + parseInt(width);
				var $videoContainer = $("<div>", {
					class: "GM_fwip_container_full",
					css: {
						"background-color": "#000",
						"position": "fixed",
						"top": "20px",
						"right": "20px",
						// "border": "5px solid #333",
						// "border-radius": "5px",
						"box-shadow": "0 0 10px 5px rgba(0,0,0,0.5)",
						"z-index": "2000000013",
					}
				});
				var $videoPlayer = $("<video>", {
					class: "GM_fwip_player",
					css: {
						"width": "auto",
						"height": "auto",
						"max-width": $(window).width() - offset - 40,
						"max-height": $(window).height() - 40,
					},
				}).prop({
					autoplay: true,
					loop: USE_LOOP,
					muted: USE_MUTED,
					preload: true,
				}).append(
					$("<source>", {
						src: href,
						type: "video/webm",
						error: function() {
							// ソースの読み込み失敗イベント
							onerror();
						},
					})
				);
				$videoContainer.append($videoPlayer);
				if (USE_TIME_DISPLAY) {
					$videoPlayer.on("loadedmetadata", function(){
						// メタデータ読み込み完了イベント
						showDuration($(this).get(0));
					}).on("timeupdate", function() {
						// 再生位置変更イベント
						showCurrentTime($(this).get(0));
					});
					$videoContainer.append(
						$("<div>", {
							class: "GM_fwip_time_container",
							css: {
								"font-size": "6pt",
								"font-family": "arial,helvetica,sans-serif",
								postion: "relative",
								"text-align": "right",
								color: "#fff",
							}
						}).append(
							$("<span>", {
								class: "GM_fwip_time_current"
							})
						).append(
							$("<span>").text("/")
						).append(
							$("<span>", {
								class: "GM_fwip_time_duration",
							})
						)
					);
				}
				$("body").append($videoContainer);
				// 動画の長さを表示する
				function showDuration(video) {
					var webm_duration = parseTime(video.duration);
					$(".GM_fwip_time_duration").text(webm_duration);
				}
				// 再生時間を表示する
				function showCurrentTime(video) {
					var currenttime = parseTime(video.currentTime);
					$(".GM_fwip_time_current").text(currenttime);
				}
				// エラー表示
				function onerror() {
					$videoContainer.children().remove();
					$videoContainer.append(
						$("<p>", {
							text: "動画が読み込めませんでした",
							class: "GM_fwip_error",
							css: {
								"text-align": "center",
								"background-color": "#fff",
								"color": "#c00"
							}
						})
					);
				}
			}
			// フルプレーヤーを消す
			function hideFullPlayer() {
				var $container = $(".GM_fwip_container_full");
				if ($container.length) {
					$container.remove();
				}
			}
		}
		// 秒をhh:mm:ss形式で返す
		function parseTime(sec) {
			var date = new Date(0,0,0,0,0,sec);
			var time = 
				("0" + date.getHours()).slice( -2 ) + ":" +
				("0" + date.getMinutes()).slice( -2 ) + ":" +
				("0" + date.getSeconds()).slice( -2 );
			return time;
		}
	}

})(jQuery);