Gives you a seekbar, autoplay option, volume options, etc.
// ==UserScript== // @name BYTS(Better YouTube Shorts) - Greasyfork Edition // @version 1.2.9 // @description Gives you a seekbar, autoplay option, volume options, etc. // @author Taki7o7 aka. WaGi-Coding // @match *://www.youtube.com/shorts/* // @require http://code.jquery.com/jquery-latest.js // @run-at document-idle // @grant GM_addStyle // @grant GM.getValue // @grant GM.setValue // @license GPLv3 // @namespace https://greasyfork.org/users/772124 // ==/UserScript== GM_addStyle(` input[type=range].volslider { height: 14px; -webkit-appearance: none; margin: 10px 0; } input[type=range].volslider:focus { outline: none; } input[type=range].volslider::-webkit-slider-runnable-track { height: 8px; cursor: pointer; box-shadow: 0px 0px 0px #000000; background: rgb(50 50 50); border-radius: 25px; border: 1px solid #000000; } input[type=range].volslider::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; margin-top: -7px; border-radius: 0px; background-image: url('https://i.imgur.com/vcQoCVS.png'); background-size:20px; background-repeat: no-repeat; background-position: 50%; } input[type=range]:focus::-webkit-slider-runnable-track { background: rgb(50 50 50); } .switch { position: relative; display: inline-block; width: 46px; height: 20px; } .switch input { opacity: 0; width: 0; height: 0; } .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: .4s; transition: .4s; } .slider:before { position: absolute; content: ""; height: 12px; width: 12px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: .4s; transition: .4s; } input:checked + .slider { background-color: #FF0000; } input:focus + .slider { box-shadow: 0 0 1px #FF0000; } input:checked + .slider:before { -webkit-transform: translateX(26px); -ms-transform: translateX(26px); transform: translateX(26px); } /* Rounded sliders */ .slider.round { border-radius: 12px; } .slider.round:before { border-radius: 50%; } `); var $ = window.jQuery; var vid = null; var reel = null; var udTimer = null; var progbar = null; var seekMouseDown = false; var bytsVol = null; var bytsTimeInfo = null; var lastCurSeconds = 0; // var xhr = new XMLHttpRequest(); // var windloc = ''; // Storage var savedVolume = 1.0; var autoScrollVal = true; // ------- async function LoadSettings() { savedVolume = await GM.getValue('bytsVolume', 1.0); autoScrollVal = await GM.getValue('bytsAutoscroll', true); } function findValues(obj, key) { return findValuesHelper(obj, key, []); } function findValuesHelper(obj, key, list) { if (!obj) return list; if (obj instanceof Array) { for (var i in obj) { list = list.concat(findValuesHelper(obj[i], key, [])); } return list; } if (obj[key]) list.push(obj[key]); if ((typeof obj == "object") && (obj !== null)) { var children = Object.keys(obj); if (children.length > 0) { for (i = 0; i < children.length; i++) { list = list.concat(findValuesHelper(obj[children[i]], key, [])); } } } return list; } window.onload = function () { var checkExist = setInterval(() => { // wait until any video elements rendered if ($('ytd-shorts').length && $('.html5-video-player').length) { clearInterval(checkExist); LoadSettings(); setInterval(updateVidElem, 50); // windloc = window.location.href; // setInterval(() => { // if(windloc != window.location.href){ // windloc = window.location.href; // xhr.abort(); // } // }, 20); udTimer = setInterval(AddUploadDateIfNeeded, 50); addEventListener("keydown", function (e) { switch (e.key.toUpperCase()) { case "ARROWLEFT": $(vid).prop('currentTime', $(vid).prop('currentTime') - 2) break; case "ARROWRIGHT": $(vid).prop('currentTime', $(vid).prop('currentTime') + 2) break; default: break; } }); } }, 100); } function padTo2Digits(num) { return num.toString().padStart(2, '0'); } function updateVidElem() { if ($('ytd-reel-video-renderer').length >= 28) { $('ytd-reel-video-renderer:lt(9)').remove(); } vid = $('.html5-video-player').first().find('video').first(); if ($(vid).length === 0) { return; } $(vid).prop('volume', $('#byts-vol').val()); if (autoScrollVal == true) { $(vid).removeAttr('loop'); $(vid).unbind('ended'); $(vid).on('ended', function () { //console.log("ended"); $('#navigation-button-down').find("button").first().click(); }); } else { $(vid).attr('loop', true); $(vid).unbind('ended'); } reel = $(vid).closest('ytd-reel-video-renderer'); if ($(reel).length === 0) { return; } if ($(reel).find('#byts-progbar').length === 0) { if ($('#byts-progbar').length === 0) { $(reel).append('<div id="byts-progbar" style="user-select: none; cursor: pointer; width: 100%; height: 14px; background-color: #343434; position: absolute; margin-top: -20px; border-radius: 10px;"></div>'); } else { $(reel).append($('#byts-progbar')); } progbar = $('#byts-progbar').first(); $(progbar).mousemove((e) => { if (seekMouseDown) { $(vid).prop('currentTime', (e.offsetX * 1 / $(reel).outerWidth()) * $(vid).prop('duration')); } }); $(progbar).mousedown(() => { seekMouseDown = true; }); $(progbar).mouseleave(() => { seekMouseDown = false; }); $(progbar).mouseup((e) => { seekMouseDown = false; $(vid).prop('currentTime', (e.offsetX * 1 / $(reel).outerWidth()) * $(vid).prop('duration')); }); } let time = ($(vid).prop('currentTime') / $(vid).prop('duration')) * 100; var progress = document.getElementById('byts-progress'); if (progress == null) { progress = document.createElement("div"); progress.setAttribute("id", "byts-progress"); progress.style.userSelect = "none"; progress.style.backgroundColor = "#FF0000"; progress.style.height = "100%"; progress.style.borderRadius = "10px"; progress.style.width = time + "%"; progress.onmouseup = function (e) { var selected_val = e.offsetX * 1 / $(reel).outerWidth(); $(vid).prop('currentTime', selected_val * $(vid).prop('duration')); } $(progbar).append(progress); } else { progress.style.width = time + "%"; } // Time Info let durSecs = Math.floor($(vid).prop('duration')); let durMinutes = Math.floor(durSecs / 60); let durSeconds = durSecs % 60; let curSecs = Math.floor($(vid).prop('currentTime')); if (curSecs != lastCurSeconds || $(reel).find('#byts-timeinfo').length === 0) { lastCurSeconds = curSecs; let curMinutes = Math.floor(curSecs / 60); let curSeconds = curSecs % 60; // TimeInfo Element if ($(reel).find('#byts-timeinfo').length === 0) { if ($('#byts-timeinfo').length === 0) { $(reel).append('<div id="byts-timeinfo" style="user-select: none; display: flex; right: auto; left: auto; position: absolute; margin-top: ' + ($(reel).height() + 2) + 'px;"><div id="byts-timeinfo-textdiv" style="display: flex; margin-right: 5px; margin-top: 4px; color: white; font-size: 1.2rem;">' + `${curMinutes}:${padTo2Digits(curSeconds)} / ${durMinutes}:${padTo2Digits(durSeconds)}` + '</div></div>'); } else { $(reel).append($('#byts-timeinfo')); } bytsTimeInfo = $('#byts-timeinfo'); } $('#byts-timeinfo-textdiv').text(`${curMinutes}:${padTo2Digits(curSeconds)} / ${durMinutes}:${padTo2Digits(durSeconds)}`); } $('#byts-timeinfo').css('margin-top', $(reel).height() + 2); // Volume Slide if ($(reel).find('#byts-vol').length === 0) { if ($('#byts-vol').length === 0) { $(reel).append('<input style="user-select: none; width: 100px; left: 0px; background-color: transparent; position: absolute; margin-top: ' + ($(reel).height() + 5) + 'px;" type="range" id="byts-vol" class="volslider" name="vol" min="0.0" max="1.0" step="0.01" value="' + savedVolume + '"></input>'); } else { $(reel).append($('#byts-vol')); } bytsVol = $('#byts-vol'); $('#byts-vol').on('input change', function () { $(vid).prop('volume', $(this).val()); GM.setValue('bytsVolume', $(this).val()); }); } $('#byts-vol').css('margin-top', $(reel).height() + 5); // AutoScroll if ($(reel).find('#byts-autoscroll-div').length === 0) { if ($('#byts-autoscroll-div').length === 0) { let astc = ''; if (autoScrollVal) { astc = ' checked'; } $(reel).append('<div id="byts-autoscroll-div" style="user-select: none; display: flex; right: 0px; position: absolute; margin-top: ' + ($(reel).height() + 2) + 'px;"><div style="display: flex; margin-right: 5px; margin-top: 4px; color: white; font-size: 1.2rem;">Auto-Scroll: </div><label class="switch"><input id="byts-autoscroll-input" type="checkbox"' + astc + '><span class="slider round"></span></label></div>'); } else { $(reel).append($('#byts-autoscroll-div')); } bytsVol = $('#byts-autoscroll-div'); $('#byts-autoscroll-input').on('input change', function () { // console.log($(this).is(':checked')); GM.setValue('bytsAutoscroll', $(this).is(':checked')); if ($(this).is(':checked')) { autoScrollVal = true; } else { autoScrollVal = false; } if (autoScrollVal == true) { $(vid).removeAttr('loop'); $(vid).unbind('ended'); $(vid).on('ended', function () { //console.log("ended"); $('#navigation-button-down').find("button").first().click(); }); } else { $(vid).attr('loop', true); $(vid).unbind('ended'); } // $(vid).prop('volume', $(this).val()); }); } $('#byts-autoscroll-div').css('margin-top', $(reel).height() + 2); } async function AddUploadDateIfNeeded() { if ($(vid).length === 0) { return; } if ($(reel).length === 0) { return; } if ($(reel).find('#channel-name').find('#byts-uploaddate').length === 0) { clearInterval(udTimer); try { let reelId = $(reel).attr('id'); // for skipping when we switch to another video before the promise is done let html = ''; //xhr.abort(); // xhr = await $.get(window.location.href, function (data) { await $.get(window.location.href, function (data) { try{ if(reelId != $(reel).attr('id') || $(reel).find('#channel-name').find('#byts-uploaddate').length !== 0){ //xhr.abort(); udTimer = setInterval(AddUploadDateIfNeeded, 50); return; } html = data; // let jsonString = html.match('(?<=var ytInitialData = ).*(?=;</script>)'); let jsonString = html.substring(html.indexOf('var ytInitialData = ')); jsonString = jsonString.substring("var ytInitialData = ".length, jsonString.indexOf(';</script>')); let jObj = JSON.parse(jsonString); let ulDate = findValues(jObj, 'publishTimeText')[0].runs[1].text; let viewObj = findValues(jObj, 'viewCountText')[0].runs; let views = viewObj[0].text; let viewsText = viewObj[1].text; let displayText = ''; views = views.replaceAll(',', '.'); if (typeof ulDate == 'undefined') { ulDate = ''; } if(typeof viewObj != 'undefined'){ displayText = '<br>' + views + ' ' + viewsText; } if(typeof ulDate != 'undefined' || typeof viewObj != 'undefined'){ $(reel).find('#channel-name').find('#text').append('<span id="byts-uploaddate"><br>' + ulDate + displayText + '</span>'); } }catch{ udTimer = setInterval(AddUploadDateIfNeeded, 50); return; } }); udTimer = setInterval(AddUploadDateIfNeeded, 50); } catch (error) { udTimer = setInterval(AddUploadDateIfNeeded, 50); return; } } }