您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows complete video thumbnails for YouTube videos
当前为
- // ==UserScript==
- // @name YouTube Thumbnails - Full Video Thumbnails for YouTube
- // @namespace driver8.net
- // @description Shows complete video thumbnails for YouTube videos
- // @match *://*.youtube.com/watch?*
- // @version 0.3.2
- // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
- // @grant GM_addStyle
- // @grant unsafeWindow
- // @grant GM_registerMenuCommand
- // @grant GM_getValue
- // @grant GM_setValue
- // ==/UserScript==
- var AND_BUTTS = false;
- var LOAD_DELAY_START = 200;
- var LOAD_DELAY_FACTOR = 50;
- var LOAD_DELAY_MAX = 500;
- var TIMEOUT_DELAY = 2000;
- var DIV_PADDING = 10;
- var TD_PADDING = 2;
- var DISABLE_SPF = GM_getValue('ytDisableSPF', false);
- var LOGGING = false;
- var MIN_WIDTH = 4;
- var MAX_IMAGES = 30;
- var $thumbDiv, $thumbHeader, storyboard_spec, storyboard, best_size_idx, best_size, len_seconds, videoId, tries;
- function log(msg) {
- LOGGING && console.log(msg);
- }
- log("Hi");
- setUp();
- function setUp() {
- AND_BUTTS && $('#eow-title').text($('#eow-title').text() + " and Butts");
- // See if waiting will help w/spf bullshit (it won't)
- tries = 0;
- (function trySb() {
- try {
- storyboard_spec = unsafeWindow.ytplayer.config.args.storyboard_spec;
- } catch (e) {
- log("oops " + e);
- try {
- storyboard_spec = window.ytplayer.config.args.storyboard_spec;
- } catch (e2) {
- log("oops2 " + e2);
- if (tries++ < 2) {
- window.setTimeout(trySb, TIMEOUT_DELAY);
- }
- }
- }
- })();
- storyboard = parseStoryboardSpec(storyboard_spec);
- best_size_idx = chooseBestStoryboardSize(storyboard);
- best_size = storyboard.sizes[best_size_idx];
- log(best_size);
- len_seconds = parseInt(unsafeWindow.ytplayer.config.args.length_seconds);
- log("len: " + len_seconds);
- var $titleDiv = $('#watch-header');
- $thumbDiv = $('<div id="thumbDiv" class="yt-card"></div>');
- $thumbHeader = $('<h1 width="100%">Thumbs</h1>');
- $thumbDiv.append($thumbHeader);
- $titleDiv.after($thumbDiv);
- $thumbDiv.click(showThumbs);
- log("Script done");
- styleIt();
- }
- function showThumbs(event) {
- var duration = best_size.duration / 1000;
- var num_thumbs = 1;
- if (duration > 0) {
- num_thumbs = Math.ceil(len_seconds / duration / best_size.cols / best_size.rows);
- } else {
- duration = len_seconds / best_size.cols / best_size.rows;
- }
- log("Thumb header clicked. Loading " + num_thumbs + " images.");
- var total_width = best_size.width * best_size.cols + DIV_PADDING * 2;
- var parent_diff = $thumbDiv.parent().innerWidth() - total_width;
- parent_diff < 0 && $thumbDiv.css({'left': + parent_diff + 'px'});
- $thumbDiv.css({'position': 'relative', 'width': total_width + 'px'});
- // Grab the youtube sessionlink ID for time links
- var sessionlink = $('#logo-container').data("sessionlink");
- var badImage = false;
- (function loadImage(imgNum) {
- if (badImage === false && imgNum < num_thumbs && imgNum < MAX_IMAGES) {
- // EX: https:\/\/i.ytimg.com\/sb\/2XY3AvVgDns\/storyboard3_L$L\/$N.jpg
- // EX: https://i.ytimg.com/sb/k4YRWT_Aldo/storyboard3_L2/M0.jpg?sigh=RVdv4fMsE-eDcsCUzIy-iCQNteI
- var link = storyboard.baseUrl.replace('\\', '');
- link = link.replace('$L', best_size_idx);
- link = link.replace('$N', best_size.img_name);
- link = link.replace('$M', imgNum);
- link += '?sigh=' + best_size.sigh;
- log(link);
- // Create a table for the timestamps over the image
- var $newTable = $('<table>');
- $newTable.addClass('imgTable');
- var x = imgNum * duration * best_size.rows * best_size.cols; // the starting time for this table
- var innerStr = '';
- var doclocation = document.location.href.replace(/\#.*/, '');
- for (var i = 0; i < best_size.rows; i++) {
- if (x <= len_seconds + 1) { // if we haven't reached the end of the video
- innerStr += '<tr>';
- for (var j = 0; j < best_size.cols; j++) {
- innerStr += '<td><a class="yt-uix-sessionlink" href="' + doclocation + '#t=' + x + '">';
- if (x <= len_seconds + 1) {
- var hrs = Math.floor(x / 3600);
- var mins = Math.floor((x % 3600) / 60);
- var secs = Math.round(x % 60);
- innerStr += hrs > 0 ? hrs + ':' : ''; // hrs
- innerStr += ( hrs > 0 && mins < 10 ? "0" + mins : mins ) + ':'; // mins
- innerStr += secs < 10 ? "0" + secs : secs; // secs
- }
- innerStr += '</a></td>';
- x += duration;
- }
- innerStr += '<tr>';
- }
- }
- $newTable.html(innerStr);
- $newTable.error(function() {
- badImage = true;
- $(this).remove();
- log("Hid bad image");
- });
- //$newTable.load(function() {
- // loadImage(imgNum + 1);
- //});
- $newTable.css({'background-image': 'url(' + link + ')', 'width': best_size.width * best_size.cols});
- $thumbDiv.append($newTable);
- setTimeout(loadImage, Math.min(LOAD_DELAY_START + imgNum * LOAD_DELAY_FACTOR, LOAD_DELAY_MAX), imgNum + 1);
- }
- })(0);
- log("Done making thumb div");
- $thumbDiv.off('click');
- $thumbDiv.click(hideThumbs);
- }
- function hideThumbs(event) {
- if ($(event.target).is('#thumbDiv, #thumbDiv h1')) {
- $thumbDiv.children('table').hide();
- $thumbDiv.off('click');
- $thumbDiv.click(showThumbsAgain);
- } else {
- $('html, body').scrollTop(0);
- }
- }
- function showThumbsAgain(event) {
- if ($(event.target).is('#thumbDiv, #thumbDiv h1')) {
- $thumbDiv.children('table').show();
- $thumbDiv.off('click');
- $thumbDiv.click(hideThumbs);
- }
- }
- function parseStoryboardSpec(spec) {
- // EX: https:\/\/i.ytimg.com\/sb\/Pk2oW4SDDxY\/storyboard3_L$L\/$N.jpg|48#27#100#10#10#0#default#vpw4l5h3xmm2AkCT6nMZbvFIyJw|80#45#90#10#10#2000#M$M#hCWDvBSbgeV52mPYmOHjgdLFI1o|160#90#90#5#5#2000#M$M#ys1MKEnwYXA1QAcFiugAA_cZ81Q
- var sections = spec.split('|');
- log(sections);
- var sb = {
- sizes: [],
- baseUrl: sections.shift()
- };
- // EX: 80#45#90#10#10#2000#M$M#hCWDvBSbgeV52mPYmOHjgdLFI1o
- // EX: 160# 90# 90# 5# 5# 2000# M$M# ys1MKEnwYXA1QAcFiugAA_cZ81Q
- sections.forEach(function(value, idx) {
- var data = value.split('#');
- log(data);
- var new_size = {
- width : +data[0],
- height : +data[1],
- qual : +data[2], // image quality???
- cols : +data[3],
- rows : +data[4],
- duration : +data[5], // duration of each snapshot in milliseconds
- img_name : data[6],
- sigh : data[7]
- };
- sb.sizes[idx] = new_size;
- });
- log(sb);
- return sb;
- }
- function chooseBestStoryboardSize(sb) {
- var sizes = sb.sizes;
- var widest = 0;
- var widest_idx = -1;
- for (var i = 0; i < sizes.length; i++) {
- if (widest < sizes[i].width || (widest == sizes[i].width && sizes[widest_idx].cols < sizes[i].cols)) {
- if (sizes[i].cols >= MIN_WIDTH) {
- widest = sizes[i].width;
- widest_idx = i;
- }
- }
- }
- return widest_idx;
- }
- function styleIt() {
- var userStyles0 =
- "table.imgTable { border-collapse: collapse; background-repeat: no-repeat; cursor: auto; !important } " +
- ".imgTable td { width: " + (best_size.width - 2 * TD_PADDING) + "px;" +
- " height: " + (best_size.height - 2 * TD_PADDING) + "px;" +
- " padding: " + TD_PADDING + "px;" +
- " border-width: 0px;" +
- " vertical-align: top;" +
- " color: white;" +
- " text-shadow:" +
- " -1px -1px 0 #000, " +
- " 1px -1px 0 #000, " +
- " -1px 1px 0 #000, " +
- " 1px 1px 0 #000; " +
- " !important}" +
- ".imgTable a { text-decoration: none; color: white; display: block; width: 100%; height: 100% !important }" +
- "#thumbDiv {padding: " + DIV_PADDING + "px; cursor: pointer; }";
- GM_addStyle(userStyles0);
- if (DISABLE_SPF) {
- $('a.spf-link').each(function () {
- var $link = $(this);
- $link.removeClass('spf-link');
- $link.off();
- });
- }
- GM_registerMenuCommand( "Toggle SPF", function toggleSpf() {
- DISABLE_SPF = !DISABLE_SPF;
- GM_setValue('ytDisableSPF', DISABLE_SPF);
- }, 's' );
- log("DONE");
- }
- /// TRYING TO DEAL WITH YOUTUBE'S STUPID SPF SHIT WITHOUT DISABLING IT. BLAHH! ///
- //window.addEventListener('spfrequest', function() { log("SPF WUT? spfrequest"); });
- //window.addEventListener('spfpartprocess', function() { log("SPF WUT? spfpartprocess"); });
- //window.addEventListener('spfpartdone', function() { log("SPF WUT? spfpartdone"); });
- //window.addEventListener('spfprocess', function() { log("SPF WUT? spfprocess"); });
- //window.addEventListener('spfdone', function() { log("SPF WUT? spfdone"); });
- //window.addEventListener('spferror', function() { log("SPF WUT? spferror"); });
- //window.addEventListener('spfreload', function() { log("SPF WUT? spfreload"); });
- //window.addEventListener('spfjsbeforeunload', function() { log("SPF WUT? spfjsbeforeunload"); });
- //window.addEventListener('spfdone', spfWut);
- //function spfWut(a) {
- // log(a);
- // var parts = a.detail.response.parts;
- // var good_part = null;
- // parts.forEach(function(val, idx) {
- // good_part = good_part || (val.data && val.data.swfcfg);
- // });
- // log(good_part);
- // // var storyboard_spec = a.data.swfcfg.args.storyboard_spec;
- // storyboard_spec = good_part.args.storyboard_spec;
- // log("sbSpec: " + sb_spec);
- // best_size_idx_idx = chooseBestStoryboardSize(storyboard);
- // best_size = storyboard.sizes[best_size_idx_idx];
- // log(best_size);
- // len_seconds = parseInt(good_part.args.length_seconds);
- // log("len: " + len_seconds);
- // setUp();
- // log("BOOM");
- //}
- //
- //(function transitionCheck() {
- // $('body').on('transitionend', function(event) {
- // log("transitioned prog");
- // if (event.target.id != 'progress') return false;
- // log("transitioned event");
- // setUp();
- // log("BOOM");
- // transitionCheck();
- // });
- //})();