YouTube screenshot

Adds a screenshot button to YouTube video page

// ==UserScript==
// @name        YouTube screenshot
// @namespace   https://github.com/qiwichupa/userscripts/blob/master/youtube_screenshot__userscript
// @homepage    https://greasyfork.org/ru/scripts/455155-youtube-screenshot
// @author      qiwichupa
// @version     20221120.2147
// @description Adds a screenshot button to YouTube video page
// @match       *://www.youtube.com/*
// @match       *://youtube.com/*
// @run-at      document-end
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// @grant        none
// @license           GNU General Public License v2.0 or later
// ==/UserScript==
 
this.$ = this.jQuery = jQuery.noConflict(true);
$(function () {
 
    "use strict";
    addScreenshotSupport();
    document.body.addEventListener("yt-navigate-finish", function (event) {
        addScreenshotSupport();
    });
 
 
    function addScreenshotSupport(firstLoad) {
        if (isVideoPage()) {
            waitForElement("upload-info", function () {
                addScreenshotButton();
            }, 330);
        }
    }
 
 
    function waitForElement(elementId, callbackFunction, intervalLength = 330) {
        var waitCount = 15000 / intervalLength; // wait 15 seconds maximum
        var wait = setInterval(function () {
            waitCount--;
            if ($("#" + elementId).length > 0) {
                callbackFunction();
                clearInterval(wait);
            } else if (waitCount <= 0) {
                console.log("YouTube RSS Feed UserScript - wait for element \"#" + elementId +
                        "\" failed! Time limit (15 seconds) exceeded.");
                clearInterval(wait);
            }
        }, intervalLength);
    }
 
    function isVideoPage() {
        return document.URL.indexOf("/watch") !== -1 && document.URL.indexOf("v=") !== -1;
    }
 
 
    function addScreenshotButton() {
        if ($("#ScreenshotButton").length > 0) {
            $("#ScreenshotButton").remove();
        }
        $("#subscribe-button")
                .css({
                    "display": "flex",
                    "flex-flow": "nowrap",
                    "height": "37px"
                })
                .prepend(styleOfScreenshotButton());
      $("#ScreenshotButton").click (makeScreenshot);
    }
 
 
    function styleOfScreenshotButton() {
        return $('<button id="ScreenshotButton" onclick="makeScreenshot()">SHOT</button>')
                .css({
                    "background-color": "#fd9b12",
                    "border-radius": "3px",
                    "padding": "10px 16px",
                    "color": "#ffffff",
                    "font-size": "14px",
                    "text-decoration": "none",
                    "text-transform": "uppercase",
                    "margin-right": "5px"
                });
    }
 
 
    function makeScreenshot () {
        // original code: https://github.com/ReeganExE/youtube-screenshot
        // and https://github.com/ParticleCore/Iridium
        var screen_shot_container;
        var canvas;
        var video;
        var aspect_ratio;
        var canvas_context;
        var aspect_ratio;
        var canvas_width;
        var canvas_height;
        var base64ImageData;
        var filename;
        var a;
        var img;
 
        if (!(screen_shot_container = document.getElementById("us-screen-shot-container"))) {
 
                              screen_shot_container           = document.createElement("template");
                              screen_shot_container.innerHTML =
                                  "<div id='us-screen-shot-container'>" +
                                  "    <a target='_blank' download data-locale='title|screen_shot_title'>" +
                                  "        <canvas></canvas>" +
                                  "    </a>" +
                                  "</div>";
                              screen_shot_container           = screen_shot_container.content;
 
                          }
 
        canvas = screen_shot_container.querySelector("canvas");
        video = document.querySelector('video');
        aspect_ratio   = video.videoWidth / video.videoHeight;
 
        // Change the size here
        canvas_context = canvas.getContext("2d");
        aspect_ratio   = video.videoWidth / video.videoHeight;
        canvas_width   = video.videoWidth;
        canvas_height  = parseInt(canvas_width / aspect_ratio, 10);
        canvas.width   = canvas_width;
        canvas.height  = canvas_height;
        canvas_context.drawImage(video, 0, 0, canvas_width, canvas_height);
 
        // Won't work on file:/// URLs. SecurityError: Tainted canvases may not be exported.
        base64ImageData = canvas.toDataURL('image/jpeg');
        filename = 'snap-' + canvas.width + 'x' + canvas.height + '-' + video.currentTime + '.jpg';
 
        // Wrap <img> in link to download image because
        // the context menu Save Image as... is blocked for security reasons
        a = document.createElement('a');
        a.download = filename;
        a.href = base64ImageData;
 
        img = document.createElement('img');
        img.src = base64ImageData;
        img.alt = filename;
        img.title = 'Click to save ' + filename;
 
        window.open().document.body.appendChild(a).appendChild(img);
 
    }
 
});