Adds a button on YouTube, Imgur and SoundCloud to open current resource in yt.aergia.eu looper
当前为
// ==UserScript==
// @name yt-looper
// @description Adds a button on YouTube, Imgur and SoundCloud to open current resource in yt.aergia.eu looper
// @version 1.7.8
// @namespace https://yt.aergia.eu
// @icon https://ipfs.io/ipfs/QmZFXPq9xMJY3Z8q2fq4wfsU93uTpVfjbiaYzwFmfnkCfM
// @match https://www.youtube.com/*
// @match https://youtube.com/*
// @match http://www.youtube.com/*
// @match http://youtube.com/*
// @match https://imgur.com/*
// @match http://imgur.com/*
// @match http://soundcloud.com/*
// @match https://soundcloud.com/*
// @license CC0; https://creativecommons.org/publicdomain/zero/1.0/
// @homepageURL https://github.com/lidel/yt-looper/#companion-userscript
// @supportURL https://github.com/lidel/yt-looper/issues
// @require https://cdn.jsdelivr.net/jquery/3.2.0/jquery.min.js
// @grant none
// @noframes
// ==/UserScript==
'use strict';
(function ($, undefined) { // eslint-disable-line no-unused-vars
var youtubeHandler = function () {
var atWatchPage = window.location.pathname.startsWith('/watch');
if (atWatchPage && $('#yt-looper').length === 0) {
var humanize = function (sec) {
var sec_num = parseInt(sec, 10);
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
hours = hours > 0 ? (hours + 'h') : '';
minutes = minutes > 0 ? (minutes + 'm') : '';
seconds = seconds > 0 ? (seconds + 's') : '';
return sec === 0 ? '0s' : hours + minutes + seconds;
};
var getYtPlayer = function () {
var doc = window.document;
var ytplayer = doc.getElementById('movie_player') || doc.getElementById('movie_player-flash');
return ytplayer;
};
var playlistMode = function () {
return /list=/.test(window.location.href);
};
var renderLooperActions = function() {
$('#yt-looper-start').remove();
$('#yt-looper-end').remove();
$('#yt-looper').remove();
$('#yt-looper-interval').remove();
var $button = $('<button id="yt-looper" class="yt-uix-button yt-uix-button-opacity yt-uix-button-has-icon yt-uix-tooltip" title="Open in yt-looper"><span style="margin:0 0.1em;font-size:2.25em;vertical-align: middle;">↻</span> yt.aergia.eu </button>').hide();
var $intervals = $('<span id="yt-looper-interval"></span>').hide();
var input = '<input class="yt-uix-form-input-text title-input" style="width:50px!important;margin-right:0.25em;" />';
var $secondaryActions = $('div.watch-action-buttons > div.watch-secondary-actions');
var start = humanize(0);
var end = humanize(getYtPlayer().getDuration());
var $start = $(input).attr('id', 'yt-looper-start').val(start).attr('title', 'Start of loop');
var $end = $(input).attr('id', 'yt-looper-end').val(end).attr('title', 'End of loop');
$secondaryActions.prepend($button);
if (!playlistMode()) { // disable start/end picker when in playlist mode (did not work correct anyway)
$intervals.append($start).append($end).insertBefore($button);
}
$button.show();
$button.click(function () {
var url = window.location.href;
url = url.replace(/.*youtube.com\/watch\?/, 'https://yt.aergia.eu/#');
if (playlistMode()) {
url = url.replace(/[&#]t=[^&#]*/g, '');
} else if (getYtPlayer().getPlayerState() === 2) {
url = url.replace(/[&#]t=[^&#]*/g, '');
url = url + '#t=' + $('#yt-looper-start').val() + ';' + $('#yt-looper-end').val();
}
window.open(url);
});
};
var initButton = function() {
var newVideo = true;
window.ytLooperStateChanged = function (state) {
if (state === 2) {
$('#yt-looper-start').val(humanize(getYtPlayer().getCurrentTime()));
$('#yt-looper-interval').fadeIn('slow');
} else if (state === 1) {
// youtube redraws div.watch-action-buttons AFTER 5 and -1 events
// and 1 is the only one we have after GUI stabilizes
// ANGST.
newVideo = true;
} else {
$('#yt-looper-interval').hide();
$('#yt-looper-start').val(humanize(0));
}
if (newVideo) {
renderLooperActions();
newVideo = false;
}
};
renderLooperActions();
getYtPlayer().addEventListener('onStateChange', 'ytLooperStateChanged');
};
initButton();
}
};
var imgurHandlerRenderButton = function(ids) {
var id = ids[0];
if (/[a-zA-Z0-9]+/.test(id) && ($('div.post-image img').length > 0 || $('div.post-image video').length > 0)) {
console.log('yt-looper → renderButton for ' + ids.join(', '));
var url = 'https://yt.aergia.eu/#i=' + ids.join('&i=');
var html = '<a style="pointer:cursor;text-decoration:none;color:#ccc" title="Open in yt.aergia.eu"><span style="font-size:1.5em">↻</span><br>yt.looper</a>';
var $a = $(html).click(function () {
window.open(url);
});
$('<div class="post-account" id="yt-looper">')
.data('imgurId', id)
.css('margin-left','1em')
.css('float', 'right')
.css('text-align', 'center')
.append($a)
.hide()
.prependTo($('div.post-header'))
.fadeIn('slow');
}
};
var imgurHandler = function () {
var $oldButton = $('#yt-looper');
var imgurIds = $('div.post-image-container').map(function() { return $(this).attr('id'); }).get();
if (imgurIds.length > 0 && $oldButton.data('imgurId') != imgurIds[0]) {
$oldButton.remove();
imgurHandlerRenderButton(imgurIds);
}
};
var soundCloudHandler = function () {
if ($('#yt-looper').length === 0) {
var $soundActions = $('div.l-about-top div.soundActions');
if ($soundActions.length === 1) {
console.log('soundCloudHandler(): adding yt-looper button..');
var scId = window.location.pathname.replace(/^\//, '');
var url = 'https://yt.aergia.eu/#s=' + scId;
var $button = $('<button id="yt-looper" class="sc-button sc-button-medium" title="Open in yt-looper"><span style="font-weight: 900;">↻</span> yt.aergia.eu</button>');
$button.click(function () {
window.open(url);
});
$('div.sc-button-group', $soundActions).first().append($button);
}
}
};
// since everyone does reactive gui, we just poll to see if elements are present/gone
console.log('yt-looper userscript loaded');
switch (window.location.hostname.replace('www.', '')) {
case 'youtube.com':
window.setInterval(youtubeHandler, 2000);
break;
case 'imgur.com':
window.setInterval(imgurHandler, 1000);
break;
case 'soundcloud.com':
window.setInterval(soundCloudHandler, 1000);
break;
}
}(window.jQuery.noConflict(true)));
// vim:ts=2:sw=2:et: