您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Sick of outros on your favourite creators videos? With this script simply set the outro length in seconds, apply and enjoy!
当前为
// ==UserScript== // @name Youtube outro skip // @namespace http://tampermonkey.net/ // @version 1.3 // @description Sick of outros on your favourite creators videos? With this script simply set the outro length in seconds, apply and enjoy! // @author JustDaile // @match https://www.youtube.com/watch?* // @grant GM_setValue // @grant GM_getValue // @require http://code.jquery.com/jquery-latest.js // ==/UserScript== let destroy = function(){ // // make sure we have no events binded, in the case fn() was called by interval on URL change // this will ensure that we can create clean controls for the current playlist without accidentally // having events persisting in the background. // if ($(".video-stream").unbind()) {console.log("unbinding .video-stream");} if ($("#set-outro").unbind()){console.log("unbinding #set-outro");} if ($(".outro-controls").remove()){console.log("removed controls");} } let whenReady = function(selector, callback) { if ($(selector).length) { return callback($(selector)); } else { setTimeout(function(){ whenReady(selector, callback); }, 100); } }; (function(fn){ "use strict"; var l = document.URL; console.log(l); // $(document).ready(function(){ console.log("document ready"); fn(); }); // // detect page change hashchange not working // so check every 3 seconds if current URL matches URL we started with. // handle appropriately. // setInterval(function(){ if (l != document.URL){ console.log("document url: " + l); l = document.URL; if (l === "https://www.youtube.com/") { console.log("ignoring home"); destroy(); return; } $(document).ready(function(){ destroy(); fn(); }); } }, 3000); })(function(){ whenReady(".video-stream", function($stream){ whenReady("#primary", function($container){ whenReady("#meta-contents #text.ytd-channel-name,.ytp-ce-channel-title", function($channel){ let channel = $channel.first().text(); console.log("loaded channel: " + channel); // let urlString = document.URL + '&'; // let isPlaylist = urlString.includes("list") let loadedChannel = true; let targetId = channel.split(" ").join("_"); if (isPlaylist && !GM_getValue(targetId)) { console.log("using playlist outro settings"); loadedOutroSetInSeconds = GM_getValue(urlString.match(/[\?\&]list=([^\&\#]+)[\&\#]/i)[1]); loadedChannel = false; } // var loadedOutroSetInSeconds = GM_getValue(targetId); console.log("outro set: " + (loadedOutroSetInSeconds || 0)); // // basic outro controls design prepended to the primary container. // if property length doesn't exist we can assume controls don't either. // prepend controls to #primary container // let target = isPlaylist? "playlist" : channel; console.log("target set " + (loadedChannel? "channel": "playlist") + " = " + targetId); console.log("writing outro controls"); $container.prepend( $("<div class='outro-controls'>").append( $("<h3>Youtube Skip Outro Controller V1.1</h3>") ).append( $("<input type='number' id='outro-length' placeholder='using id: " + targetId + "'/>") ).append( $("<button id='set-outro'>apply</button>") ).append( $("<div>" + target + " outro set: <span id='outro-set'>0</span> seconds</div>").css({ "padding": "2px", }) ).css({ "margin": "2px", "textAlign": "right", }) ); // let bindToStream = function(){ // hook video timeupdate, wait for outro and hit next button when time reached // if(loadedOutroSetInSeconds){ var skipOutroSeconds = parseInt(loadedOutroSetInSeconds) | 0; $stream.unbind("timeupdate").on("timeupdate", function(e){ var currentTime = this.currentTime; var duration = this.duration; if(currentTime >= duration - skipOutroSeconds){ $(".ytp-next-button")[0].click(); } }); $("#outro-set").text(loadedOutroSetInSeconds); } } // // handle apply outro in seconds // $("#set-outro").on("click", function(e){ var seconds = $("#outro-length").val().toString(); if(seconds && seconds != "" && parseInt(seconds) != NaN){ GM_setValue(targetId, seconds); loadedOutroSetInSeconds = seconds; bindToStream(); } }); bindToStream(); }); }); }); });