Greasy Fork is available in English.

BYTS(Better YouTube Shorts) - Greasyfork Edition

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;
        }
    }
}