Tildes User Script: Youtube Thumbnails Below Topic Title

unknown user
Thu, 27 Jun 2019 23:57:30 +0000

A screenshot.

Following is a user script that embeds a thumbnail into the topic header. Was supposed to be trivial, but walking around the CSRP was not that easy. Luckily, someone had written a nice useful custom Base64 encoder, because I spent more than an hour trying to get btoa to do the thing.

// ==UserScript==
// @name     tildesYoutubeThumbs
// @version  1
// @grant    GM.xmlHttpRequest
// @namespace   tildes.net
// @include     https://tildes.net/~*/*
// ==/UserScript==

let youtubeIcon = document.querySelector('div.topic-icon-youtube_com')

if(youtubeIcon !== null) {
  let youtubeLink = youtubeIcon.nextSibling.nextSibling.href;
  let youtubeID = new URL(youtubeLink).searchParams.get('v');
  let thumbnailUrl = "https://img.youtube.com/vi/" + youtubeID + "/0.jpg";

  GM.xmlHttpRequest({
    method: "GET",
    url: thumbnailUrl,
    overrideMimeType: 'text/plain; charset=x-user-defined',
    onload: function(response) {
      if(response.status === 200) {
        let thumbElement = document.createElement('img');
        let thumbParentDiv = document.createElement('div');
        let header = document.querySelector('article.topic-full > header');
        let data = "data:image/jpeg;base64," + customBase64Encode(response.responseText);
        thumbElement.src = data;
        thumbElement.style = 'width: 60%; margin: auto';
        thumbElement.id = 'gk-youtube-thumbnail';
        thumbParentDiv.style = 'width: 100%; text-align:center;';
        header.appendChild(thumbParentDiv);
        thumbParentDiv.appendChild(thumbElement);
      }
    }
  });
}

// https://stackoverflow.com/questions/8778863/downloading-an-image-using-xmlhttprequest-in-a-userscript/8781262#8781262
function customBase64Encode (inputStr) {
    var
        bbLen               = 3,
        enCharLen           = 4,
        inpLen              = inputStr.length,
        inx                 = 0,
        jnx,
        keyStr              = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
                            + "0123456789+/=",
        output              = "",
        paddingBytes        = 0;
    var
        bytebuffer          = new Array (bbLen),
        encodedCharIndexes  = new Array (enCharLen);

    while (inx < inpLen) {
        for (jnx = 0;  jnx < bbLen;  ++jnx) {
            /*--- Throw away high-order byte, as documented at:
              https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
            */
            if (inx < inpLen)
                bytebuffer[jnx] = inputStr.charCodeAt (inx++) & 0xff;
            else
                bytebuffer[jnx] = 0;
        }

        /*--- Get each encoded character, 6 bits at a time.
            index 0: first  6 bits
            index 1: second 6 bits
                        (2 least significant bits from inputStr byte 1
                         + 4 most significant bits from byte 2)
            index 2: third  6 bits
                        (4 least significant bits from inputStr byte 2
                         + 2 most significant bits from byte 3)
            index 3: forth  6 bits (6 least significant bits from inputStr byte 3)
        */
        encodedCharIndexes[0] = bytebuffer[0] >> 2;
        encodedCharIndexes[1] = ( (bytebuffer[0] & 0x3) << 4)   |  (bytebuffer[1] >> 4);
        encodedCharIndexes[2] = ( (bytebuffer[1] & 0x0f) << 2)  |  (bytebuffer[2] >> 6);
        encodedCharIndexes[3] = bytebuffer[2] & 0x3f;

        //--- Determine whether padding happened, and adjust accordingly.
        paddingBytes          = inx - (inpLen - 1);
        switch (paddingBytes) {
            case 1:
                // Set last character to padding char
                encodedCharIndexes[3] = 64;
                break;
            case 2:
                // Set last 2 characters to padding char
                encodedCharIndexes[3] = 64;
                encodedCharIndexes[2] = 64;
                break;
            default:
                break; // No padding - proceed
        }

        /*--- Now grab each appropriate character out of our keystring,
            based on our index array and append it to the output string.
        */
        for (jnx = 0;  jnx < enCharLen;  ++jnx)
            output += keyStr.charAt ( encodedCharIndexes[jnx] );
    }
    return output;
}

Comments URL: https://tildes.net/~tildes/ezb/tildes_user_script_youtube_thumbnails_below_topic_title

Votes: 15

Comments: 7