您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
WebMをページ内で再生しちゃう
// ==UserScript== // @name futaba WebM inline player // @namespace https://github.com/himuro-majika // @description WebMをページ内で再生しちゃう // @author himuro_majika // @include http://*.2chan.net/*/* // @include https://*.2chan.net/*/* // @exclude http://*.2chan.net/*/futaba.php?mode=cat* // @exclude https://*.2chan.net/*/futaba.php?mode=cat* // @exclude http://*.2chan.net/bin/* // @exclude https://*.2chan.net/bin/* // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js // @require https://greasyfork.org/scripts/1884-gm-config/code/GM_config.js?version=4836 // @version 1.10.1 // @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_LIMIT_SIZE = false; // 動画の外側をクリックして動画を閉じる var USE_CLOSE_ON_CLICK_OUTSIDE = true; // デフォルトの音量 var DEFAULT_VOLUME = 50; // ミュート状態で再生する var USE_MUTED = false; // フルサイズプレーヤーに時間を表示する var USE_TIME_DISPLAY = true; // 再生速度変更を有効にする var USE_PLAYBACK_RATE_CONTROL = true; // 赤福のオートリンクにも反応する var USE_AUTOLINK = true; init(); function init() { config(); getImgNodeThread(); getImgNodeRes(); if (USE_CLOSE_ON_CLICK_OUTSIDE) { closeOnClick(); } if ((isAkahukuEnabled() || isFutakuroEnabled()) && USE_AUTOLINK) { getAutoLinkURL(); } observeInserted(); getResPopup(); } // 赤福が有効か function isAkahukuEnabled() { return $("#akahuku_thumbnail").length > 0; } // ふたクロが有効か function isFutakuroEnabled() { return $("#master").length > 0; } // スレ画 function getImgNodeThread() { var $sure_a = $(".thre").length ? $(".thre > a > img") : $("body > form > a > img"); if (isFutakuroEnabled()) { // ふたクロ $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)); }); } // オートリンクURL function getAutoLinkURL() { var $link = $("blockquote > a"); $link.each(function() { replaceNode($(this)); }); } // 続きを読むで挿入される要素を監視 function observeInserted() { var target = $(".thre").length ? $(".thre").get(0) : $("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 }); } // 引用ポップアップ //TODO:wip function getResPopup() { // $(document).click(function(event) { // var target = event.target; // console.log(target); // webmopen(target); // }); } // 挿入されたレス function replaceNodeInserted($nodes) { var $res_inserted = $nodes.find("td > a > img"); if (isAkahukuEnabled()) { if ($res_inserted.length) { replaceNode($res_inserted); } } else if (isFutakuroEnabled()) { $res_inserted.each(function(){ replaceNode($(this)); }); } // オートリンク var $autolink_inserted = $nodes.find("blockquote > a"); if (USE_AUTOLINK && $autolink_inserted.length) { replaceNode($autolink_inserted); } } // 外側をクリックしてプレーヤーを閉じる function closeOnClick() { $(document).click(function(event) { if (event.target.className != "extendWebm") { if ($(event.target).parents(".akahuku_reply_popup").length > 0) { // akahuku_reply_popup // replaceNode($(event.target)); // return false; } else { $("div.cancelbk").each(function() { $(this).get(0).click(); }); } } }); } // ノードの書き換え function replaceNode(node) { var href = node.parent().attr("href"); if (node.attr("dummyhref")) { // オートリンク href = node.attr("dummyhref"); } else if (node.attr("href")) { href = node.attr("href"); } if (!href.match(/\.(webm|mp4)$/)) { // 拡張子.webm, .mp4以外 return; } var width = node.attr("width"); if (!width) { // オートリンク width = node.get(0).offsetWidth; } var height = node.attr("height"); var timer_show, timer_hide, timer_rate_hide; //クリックイベント // document.removeEventListener('click', thumbonclick, false); node.click(function(event) { addMiniPlayer(node); return false; }); // マウスオーバーで読み込み node.hover(function(){ if (USE_FULLPLAYER) { clearTimeout(timer_rate_hide); timer_show = setTimeout(function(){ showFullPlayer(); if (USE_PLAYBACK_RATE_CONTROL) { showplaybackRateControl(); } }, 300); } else { if (node.attr("dummyhref") || node.attr("href")) { addMiniPlayerAutoLink(); } else if (USE_AUTOPLAY) { addMiniPlayer(node); } } },function(){ if (USE_FULLPLAYER) { clearTimeout(timer_show); timer_hide = setTimeout(function(){ hideFullPlayer(); if (USE_PLAYBACK_RATE_CONTROL) { hideplaybackRateControl(); } }, 300); } }); // 再生速度変更 function showplaybackRateControl() { if ($("#GM_fwip_Rate_container").length) { return; } var $rateContainer = $("<div>", { id: "GM_fwip_Rate_container", css: { position: "absolute", // "margin-top": "5px", "margin-left": "20px", "background-color": "rgba(0,0,0,0.3)", "z-index": "100", color: "#fff", } }).hover(function(){ clearTimeout(timer_hide); }, function() { timer_rate_hide = setTimeout(function() { hideFullPlayer(); hideplaybackRateControl(); }, 300); }).append( $("<label>", { text: "再生速度x", for: "GM_fwip_Rate", }) ).append( $("<input>", { id: "GM_fwip_Rate", type: "number", step: "0.25", max: "5.0", min: "0.25", value: "1.0", css: { width: "3em", opacity: "0.7" } }) ); if (node.attr("dummyhref") || node.attr("href")) { // オートリンク node.after($rateContainer); } else { node.parent().after($rateContainer); } } // 再生速度 function hideplaybackRateControl() { $("#GM_fwip_Rate_container").remove(); } // ミニプレイヤー function addMiniPlayer(node) { var thumb = node.get(0); webmopen(thumb); var video = node.parent().parent().find(".extendWebm"); var videoDiv = video.parent(); videoDiv.css({ "margin": "0 20px", "float": "left", "clear": "left", }); if (USE_LIMIT_SIZE) { video.css({ "width": width, "height": height, }); } video.prop({ controls: USE_CONTROLS, // autoplay: USE_AUTOPLAY, loop: USE_LOOP, muted: USE_MUTED, volume: DEFAULT_VOLUME / 100, }).click(function(event) { //動画クリックでplay/pauseトグル(Chrome用) if (navigator.userAgent.indexOf("Firefox") == -1) { if (this.paused) { this.play(); } else { this.pause(); } } }).hover(function() { if (USE_AUTOPLAY && !USE_LOOP) { this.play(); } }, function() { }); } function addMiniPlayerAutoLink() { if ( ( node.attr("dummyhref") || node.attr("href") ) && node.parent().parent().get(0).tagName == "FORM" && width < 250 ) { // スレ本文のオートリンク width = 250; } var $videoContainer = $("<div>", { class: "GM_fwip_container_mini", css: { "margin": "0 20px", "float": "left", "clear": "left", } }).hover(function(){ if (USE_AUTOPLAY) { $(this).find(".GM_fwip_player").get(0).play(); } },function(){ }).append( $("<video>", { class: "GM_fwip_player", css: { "width": USE_LIMIT_SIZE ? width : "", "height": USE_LIMIT_SIZE ? height : "", }, }).prop({ controls: USE_CONTROLS, autoplay: USE_AUTOPLAY, loop: USE_LOOP, muted: USE_MUTED, volume: DEFAULT_VOLUME / 100, }).click(function(event) { //動画クリックでplay/pauseトグル(Chrome用) if (navigator.userAgent.indexOf("Firefox") == -1) { if (this.paused) { this.play(); } else { this.pause(); } } }) // .on("timeupdate", function(){ // // 再生速度変更 // $(this).prop("playbackRate", $("#GM_fwip_Rate").val()); // }) .append( $("<source>", { src: href, type: "video/webm", }) ) ); // サムネイル画像を隠す if (node.attr("dummyhref") || node.attr("href")) { // オートリンク if (!node.parent().parent().children(".GM_fwip_container_mini").length) { node.parent().before($videoContainer); } } else { node.hide(); node.parent().before($videoContainer); } } // フルプレイヤーを表示する function showFullPlayer() { if ($("#GM_fwip_Rate_container").length) { return; } 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() - 50, }, }).prop({ autoplay: true, loop: USE_LOOP, muted: USE_MUTED, preload: true, volume: DEFAULT_VOLUME / 100, // playbackRate: "1.0", }).append( $("<source>", { src: href, type: "video/webm", error: function() { // ソースの読み込み失敗イベント onerror(); }, }) ); $videoContainer.append($videoPlayer); if (USE_PLAYBACK_RATE_CONTROL) { $videoPlayer.on("timeupdate", function() { // 再生速度変更 $(this).prop("playbackRate", $("#GM_fwip_Rate").val()); }); } 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(); } } } // 設定 function config() { // 設定画面 GM_config.init("futaba WebM inline playerオプション<br>" + "(設定反映には[Save]ボタン押下後にページの再読み込みが必要です)", { "USE_LOOP" : { "section": ["共通"], "label" : "ループ再生を有効にする", "type" : "checkbox", "default" : USE_LOOP }, "DEFAULT_VOLUME" : { "label" : "デフォルトの音量(範囲は0~100。ミュートの設定が優先されます。)", "type" : "int", "default" : DEFAULT_VOLUME }, "USE_MUTED" : { "label" : "ミュート状態で再生する", "type" : "checkbox", "default" : USE_MUTED }, "USE_AUTOLINK" : { "label" : "赤福・ふたクロのオートリンク文字列に反応する", "type" : "checkbox", "default" : USE_AUTOLINK }, "USE_FULLPLAYER" : { "section": ["フルサイズプレーヤー(画面右上のスペースに表示される大きいサイズのプレーヤー)"], "label" : "フルサイズプレーヤーを使用する(オフにするとミニサイズプレーヤーが有効になります。)", "type" : "checkbox", "default" : USE_FULLPLAYER }, "USE_TIME_DISPLAY" : { "label" : "動画の下に再生時間を表示する", "type" : "checkbox", "default" : USE_TIME_DISPLAY }, "USE_PLAYBACK_RATE_CONTROL" : { "label" : "再生速度コントロールを有効にする(実験的)", "type" : "checkbox", "default" : USE_PLAYBACK_RATE_CONTROL }, "USE_AUTOPLAY" : { "section": ["ミニサイズプレーヤー(サムネ画像と置き換わるプレーヤー)"], "label" : "マウスオーバーで再生開始する", "type" : "checkbox", "default" : USE_AUTOPLAY }, "USE_CONTROLS" : { "label" : "コントロールを表示する", "type" : "checkbox", "default" : USE_CONTROLS }, "USE_CLOSE_ON_CLICK_OUTSIDE" : { "label" : "動画の外側をクリックして動画を閉じる", "type" : "checkbox", "default" : USE_CLOSE_ON_CLICK_OUTSIDE }, "USE_LIMIT_SIZE" : { "label" : "動画のサイズをサムネ画像と同サイズに制限する", "type" : "checkbox", "default" : USE_LIMIT_SIZE } }); // 設定値読み込み USE_FULLPLAYER = GM_config.get("USE_FULLPLAYER"); USE_LOOP = GM_config.get("USE_LOOP"); USE_AUTOPLAY = GM_config.get("USE_AUTOPLAY"); USE_CONTROLS = GM_config.get("USE_CONTROLS"); if (!GM_config.get("DEFAULT_VOLUME") || GM_config.get("DEFAULT_VOLUME") > 100) { DEFAULT_VOLUME = 100; GM_config.set("DEFAULT_VOLUME", 100); } else { DEFAULT_VOLUME = GM_config.get("DEFAULT_VOLUME"); } USE_MUTED = GM_config.get("USE_MUTED"); USE_TIME_DISPLAY = GM_config.get("USE_TIME_DISPLAY"); USE_PLAYBACK_RATE_CONTROL = GM_config.get("USE_PLAYBACK_RATE_CONTROL"); USE_AUTOLINK = GM_config.get("USE_AUTOLINK"); USE_LIMIT_SIZE = GM_config.get("USE_LIMIT_SIZE"); USE_CLOSE_ON_CLICK_OUTSIDE = GM_config.get("USE_CLOSE_ON_CLICK_OUTSIDE"); // 設定ボタンの表示 $("body > table:not([class])").before( $("<span>", { id: "GM_fwip_configButton", }).append( $("<a>", { text: "[WebM設定]", css: { cursor: "pointer", }, click : function(){ GM_config.open(); } }) ) ); } // 秒を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);