您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add Speed Slider to Youtube Player Settings
当前为
- // ==UserScript==
- // @name Youtube Player Speed Slider
- // @namespace youtube_player_speed_slider
- // @version 0.1.3.1
- // @description Add Speed Slider to Youtube Player Settings
- // @author Łukasz and Witold
- // @match https://*.youtube.com/*
- // @grant none
- // ==/UserScript==
- var yts = {};
- yts.option = {
- timeoutBuild: 500,
- timeoutRemove: 1000,
- lastClick: 0
- };
- yts.elements = {
- menu : null,
- speedMenu: null,
- slider: null,
- sliderLabel: null
- };
- yts.modules = [
- 'setting',
- 'i18'
- ];
- /*************************************
- * TRANSLATION *
- ************************************/
- yts.i18 = {};
- yts.i18.dic = {
- pl: {
- 'Speed': 'Szybkość',
- 'Annotation': 'Adnotacje',
- 'Settings': 'Ustawienia'
- },
- en: {
- 'Speed': 'Speed',
- 'Annotation': 'Annotation',
- 'Settings': 'Settings'
- },
- de: {
- 'Speed' : 'Geschwindigkeit',
- 'Annotation': '',
- 'Settings': 'Einstellungen'
- },
- fr:{
- 'Speed':'Vitesse',
- 'Annotation':'',
- 'Settings':'Paramètres'
- }
- };
- yts.i18.opt = {
- lang: 'en',
- default: 'en',
- map:{
- pl: 'pl',
- pl_pl: 'pl',
- en: 'en',
- en_gb: 'en',
- de: 'de',
- fr: 'fr'
- }
- };
- yts.i18.init = function () {
- yts.i18.opt.lang = yts.i18.getLang();
- };
- yts.i18.getLang = function () {
- var lang = yts.i18.filter(yts.setting.get('lang'));
- if(lang !== '' && yts.i18.isAllow(lang)){
- return yts.i18.map(lang);
- }
- lang = yts.i18.filter(yts.dom.get('html').getAttribute('lang'));
- if(lang !== '' && yts.i18.isAllow(lang)){
- return yts.i18.map(lang);
- }
- return yts.i18.opt.default;
- };
- yts.i18.isAllow = function (lang) {
- return yts.i18.opt.map.hasOwnProperty(lang);
- };
- yts.i18.t = function (pattern) {
- if(yts.i18.dic[yts.i18.opt.lang].hasOwnProperty(pattern)){
- return yts.i18.dic[yts.i18.opt.lang][pattern];
- }
- else {
- return pattern;
- }
- };
- yts.i18.filter = function (lang) {
- return lang ? lang.replace('-', '_').toLowerCase() : '';
- };
- yts.i18.map = function (lang) {
- return yts.i18.opt.map[lang];
- };
- /*************************************
- * INIT *
- ************************************/
- yts.init = function () {
- yts.player.update();
- yts.modules.forEach(function (module) {
- yts[module].init();
- });
- yts.option.lastClick = (new Date()).getTime();
- yts.dom.event(document, "spfdone", yts.player.update);
- yts.menu.reopen();
- yts.buildApp();
- };
- yts.buildApp = function () {
- yts.elements.menu = yts.dom.get('.ytp-panel-menu');
- if (yts.elements.menu !== null) {
- setTimeout(yts.menu.removeDefaultSpeed, yts.option.timeoutRemove);
- yts.menu.build();
- yts.annot.init();
- }
- else {
- setTimeout(yts.buildApp, yts.option.timeoutBuild);
- }
- };
- /*************************************
- * MENU *
- ************************************/
- yts.menu = {};
- yts.menu.build = function () {
- yts.slider.build();
- var speedMenu = yts.dom.new('div', {
- 'className': 'ytp-menuitem'
- });
- var right = yts.dom.new('div', {
- 'className': 'ytp-menuitem-content'
- });
- yts.elements.sliderLabel = yts.dom.new('div', {
- 'className': 'ytp-menuitem-label'
- });
- yts.slider.updateLabel(1);
- speedMenu.appendChild(yts.elements.sliderLabel);
- speedMenu.appendChild(right.appendChild(yts.elements.slider));
- yts.elements.menu.appendChild(speedMenu);
- yts.menu.event();
- };
- yts.menu.event = function () {
- yts.elements.menu.addEventListener('click', yts.menu.click);
- };
- yts.menu.removeDefaultSpeed = function(){
- var switchers = yts.dom.getOpt(".ytp-menuitem", {role:'menuitemcheckbox'});
- switchers[switchers.length-1].nextElementSibling.style.display = 'none';
- };
- yts.menu.reopen = function () {
- var settings_button = yts.dom.get(".ytp-settings-button");
- settings_button.click();
- settings_button.click();
- };
- yts.menu.click = function () {
- yts.option.lastClick = (new Date()).getTime();
- };
- /*************************************
- * SLIDER *
- ************************************/
- yts.slider = {};
- yts.slider.build = function () {
- yts.elements.slider = yts.dom.new('input', {
- 'className': '',
- 'type': 'range',
- 'min': 0.5,
- 'max': 4,
- 'step': 0.1,
- 'value': 1
- });
- yts.dom.event(yts.elements.slider, 'change', yts.slider.change);
- yts.dom.event(yts.elements.slider, 'input', yts.slider.move);
- };
- yts.slider.move = function (event) {
- yts.slider.updateLabel(event.target.value);
- };
- yts.slider.change = function (event) {
- yts.player.duration(event.target.value);
- };
- yts.slider.updateLabel = function (val) {
- yts.elements.sliderLabel.innerHTML = yts.i18.t('Speed') + ': ' + parseFloat(val).toFixed(1);
- };
- /*************************************
- * PLAYER *
- ************************************/
- yts.player = {};
- yts.player.update = function(){
- yts.elements.player = yts.dom.get('.html5-main-video');
- };
- yts.player.duration = function(value){
- yts.elements.player.playbackRate = value;
- };
- /*************************************
- * ANNOTATION *
- ************************************/
- yts.annot = {};
- yts.annot.init = function(){
- if(yts.setting.get('annot') !== 'on'){
- yts.observer.init(yts.elements.menu, yts.annot.change);
- }
- };
- yts.annot.change = function (mutation) {
- if(mutation.type == "attributes" && mutation.target.getAttribute('role')=="menuitemcheckbox"){
- yts.annot.switchOff();
- }
- };
- yts.annot.switchOff = function(){
- var switchers = yts.dom.getOpt(".ytp-menuitem", {role:'menuitemcheckbox'});
- if(switchers.length == 2){
- setTimeout(function (switcher) {
- if((new Date()).getTime() - yts.option.lastClick > 1000 &&
- switcher.getAttribute('aria-checked') == "true"){
- switcher.click();
- }
- },
- 500,
- switchers[1]
- );
- }
- };
- yts.annot.switchOffAlways = function(){
- yts.setting.set('annot', 'off');
- yts.annot.switchOff();
- };
- yts.annot.switchOn = function(){
- yts.setting.set('annot', 'on');
- };
- /*************************************
- * COOKIE *
- ************************************/
- yts.cookie ={};
- yts.cookie.set = function (name, value, days) {
- days = days || 366;
- var d = new Date();
- d.setTime(d.getTime() + (days*24*60*60*1000));
- var expires = "expires="+ d.toUTCString();
- document.cookie = name + "=" + value + ";" + expires + ";path=/";
- };
- yts.cookie.get = function (name) {
- name += "=";
- var ca = document.cookie.split(';');
- for(var i = 0; i <ca.length; i++) {
- var c = ca[i];
- while (c.charAt(0)==' ') {
- c = c.substring(1);
- }
- if (c.indexOf(name) == 0) {
- return c.substring(name.length,c.length);
- }
- }
- return "";
- };
- /************************************
- * DOM *
- ************************************/
- yts.dom = {};
- yts.dom.event = function (obj, event, callback) {
- obj.addEventListener(event, callback);
- };
- yts.dom.new = function (tag, option) {
- var element = document.createElement(tag);
- for (var param in option) {
- element[param] = option[param];
- }
- return element;
- };
- yts.dom.get = function (tselector, all) {
- all = all || false;
- var type = tselector.substring(0, 1);
- var selector = tselector.substring(1);
- var elements;
- if (type == "#") {
- return document.getElementById(selector);
- }
- else if (type == ".") {
- elements = document.getElementsByClassName(selector);
- }
- else{
- elements = document.querySelectorAll(tselector);
- }
- if (all) {
- return elements;
- }
- else {
- return elements.length ? elements[0] : null;
- }
- };
- yts.dom.getOpt = function(selector, option){
- var el = yts.dom.get(selector, true);
- var pass = [];
- var correct;
- for(var i =0; i< el.length; i++){
- correct = true;
- for(var prop in option){
- if(!yts.dom.has(el[i], prop, option[prop])){
- correct = false;
- break;
- }
- }
- if(correct){
- pass.push(el[i]);
- }
- }
- return pass;
- };
- yts.dom.has = function (elem, key, val) {
- if(elem.hasAttribute(key)){
- var attr = elem.getAttribute(key);
- if(val !== null){
- return attr == val;
- }
- return true;
- }
- return false;
- };
- /*************************************
- * MENU OBSERVER *
- ************************************/
- yts.observer= {};
- yts.observer.obj = null;
- yts.observer.get = function () {
- return window.MutationObserver || window.WebKitMutationObserver;
- };
- yts.observer.init = function (element, callback) {
- var MutationObserver = yts.observer.get();
- if( MutationObserver ){
- var obs = new MutationObserver(function(mutations, observer){
- callback(mutations[0]);
- });
- obs.observe( element, {
- childList: true,
- subtree: true,
- attributes:true,
- characterData:true,
- attributeOldValue:true,
- characterDataOldValue:true
- });
- }
- };
- /*************************************
- * SETTINGS *
- ************************************/
- yts.setting = {};
- yts.setting.settings = null;
- yts.setting.init = function(){
- var cookie = yts.cookie.get('yts_s');
- yts.setting.settings = JSON.parse(cookie == '' ? '{}' : cookie);
- };
- yts.setting.set = function(key, val){
- yts.setting.settings[key] = val;
- yts.cookie.set('yts_s', JSON.stringify(yts.setting.settings));
- };
- yts.setting.get = function(kay){
- return yts.setting.settings.hasOwnProperty(kay) ?
- yts.setting.settings[kay] : null;
- };
- yts.init();