Trying Out A Set Of Hacky Tampermonkey Javascript Modifications For A Better kick.com Live Stream Video Experience

The kick.com live stream video experience on the web is not the best overall, it seems to constantly lose track of a previously buffered section of the live stream and then sends you to the live portion but mine also gets stuck on reconnecting again and remains frozen until a manual refresh! I tried to write a series of hacky javascript modifications to help solve the following issues:

  • Always show the bottom video controls bar on the live stream video
  • Always set the volume level to 100% instead of the continually defaulted 50%
  • Accepts a basic timestamp parameter to seek to in a live stream video
  • Keeps track of your latest buffered video seek position
  • Auto reseeks to the last known tracked timestamp if the buffered video jumps forward to live stream and auto reloads the page with the timestamp parameter if the stream connection becomes frozen
// ==UserScript==
// @name         klol
// @namespace    http://tampermonkey.net/
// @version      2026-08-19
// @description  try to take over the world!
// @author       You
// @match        https://kick.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kick.com
// @grant        none
// @noframes
// ==/UserScript==

(function() {
    'use strict';

    var murl = location.href;
    var stop = "";
    var wait = 5;

    function mmov() {
        var elem = document.getElementsByTagName("video");
        if (elem.length > 0) {
            const mous = new MouseEvent("mousemove", { bubbles:true, cancelable:true, view:window });
            elem[0].dispatchEvent(mous);
        }
        setTimeout(mmov, 0.91 * 1000);
    }
    setTimeout(mmov, 0.91 * 1000);

    function msec(inpt) {
        var info = inpt.split(":");
        if (info.length == 3) {
            return ((parseInt(info[0]) * 3600) + (parseInt(info[1]) * 60) + parseInt(info[2]));
        }
        return 0;
    }

    var r = -1;
    var d = -2;
    function mtxt() {
        var s = location.href.replace(/\?.*$/mig, "");
        var l = document.getElementsByClassName("text-xs");
        if ((l.length > 0) && (l[0].innerText.match(/^[0-9]*:[0-9]*:[0-9]*$/mig))) {
            var t = l[0].innerText;
            var u = msec(t);
            var c = document.getElementById("channel-content");
            if (c) {
                var o = c.getElementsByClassName("min");
                if (o.length > 0) {
                    var q = document.querySelector("video");
                    var z = document.getElementById("time");
                    if (!z) {
                        o[0].innerHTML = ("<span style='font-family:Monaco;'><a href='" + s + "'><b>&lt;---&gt;</b></a> &nbsp; <span id='secs'>[X]</span> &nbsp; <span id='time'>" + t + "</span> &nbsp; </span>" + o[0].innerHTML);
                    } else {
                        var w = z.innerText;
                        var v = msec(w);
                        if (murl.includes("?t=")) {
                            var p = parseFloat(murl.replace(/^.*t=/mig, ""));
                            console.log(" TIME " + q.readyState + ":" + p);
                            const leftKey = new KeyboardEvent("keydown", { bubbles:true, cancelable:true, keyCode:37, which:37, key:"ArrowLeft", code:"ArrowLeft" });
                            document.dispatchEvent(leftKey);
                            q.currentTime = p;
                            murl = "";
                        }
                        if ((q.readyState != 0) && (q.readyState != 4) && (stop == "")) {
                            console.log(" LOAD " + q.readyState + ":" + r);
                            if (wait < 1) {
                                if (r > 15) {
                                    location.href = (s + "?t=" + r);
                                } else {
                                    location.href = s;
                                }
                                stop = "x";
                            } else {
                                wait -= 1;
                            }
                        }
                        if ((v + (15 * 60)) > u) {
                            var x = parseInt(q.currentTime);
                            if (Math.abs(x - d) > 15) {
                                var y = document.getElementById("secs");
                                r = x; d = -2;
                                z.innerText = t;
                                y.innerText = (" [" + r + "] ");
                            } else {
                                r = -1; d = x;
                            }
                        } else {
                            console.log(" KICK " + q.readyState + ":" + z.innerText);
                            q.currentTime = r;
                        }
                    }
                }
            }
        }
        setTimeout(mtxt, 1.91 * 1000);
    }
    setTimeout(mtxt, 1.91 * 1000);

    function maud() {
        var volu = document.querySelector("video");
        if (volu) { volu.volume = 1; }
        setTimeout(maud, 3.91 * 1000);
    }
    setTimeout(maud, 3.91 * 1000);
})();

Leave a comment