Search code examples
javascriptgoogle-chromegoogle-chrome-extensionyoutube

How can I change the window title of an opened youtube video to include the channel name?


Basically what I want the extension to do is, when I open a youtube video, grab the name of the youtube channel and add it to the window title so that I can block youtube videos of only some channels. So if the youtube channel name was "Mark Rober" and the video title (and thus also the window title) was "Is NASA a waste of money?" I want to change the window title into something like "Is NASA a waste of money? - Mark Rober".

I tried writing a chrome extension for this but I can't figure out how to get the name of the youtube channel to put it into the window title. I tried using document.querySelector and document.getElementById and both return "null" or undefined. Probably because I don't know how to access specifically the channel name because it doesn't really have a unique ID in the HTML.

I also thought about doing this through the YouTube API but that requires an OAuth Token. And since this extension would be really helpful to use alongside many web blockers I would love to share it when its working and with a token that might be less accessible (I think).

So if anyone can help me do this I'd be really grateful :)


Solution

  • I'm not sure what's going on in their code, maybe IDs are not unique or something, but anyway, I've managed to get the channel's name using the ugliest expression:

    document.getElementById("primary-inner").children[7].children[1].children[0].children[0].children[0].children[0].children[1].children[0].children[0].children[0].children[0].children[0].innerHTML
    

    (Are you aware of the issue that it takes time for the page to load and if the script runs before the page has finished loading you might get null? There are techniques to overcome this issue, in case it's new to you.)


    Edit:

    The full code of a Chrome extension that works for me:

    displayChannelName.js:

    console.log("displayChannelName started.");
    
    let nodeLoaded = setInterval(function () {
        let node = document.getElementById("primary-inner");
        if (node != undefined) {
            let channelName = node.children[7].children[1].children[0].children[0].children[0].children[0].children[1].children[0].children[0].children[0].children[0].children[0].innerHTML;
            console.log("channel name: " + channelName);
            document.title = document.title + " - " + channelName;
            clearInterval(nodeLoaded);
        };
    }, 500);
    

    manifest.json:

    {
      "name": "YouTube Channel Name",
      "version": "1",
      "description": "Display YouTube Channel Name",
      "manifest_version": 3,
      "content_scripts": [ {
          "matches": ["https://www.youtube.com/watch*"],
          "js": ["displayChannelName.js"]
        } ]
    }
    

    Edit:

    With MutationObserver:

    displayChannelName.js:

    console.log("displayChannelName script started.");
    let currTitle;
    
    function updateTitle(node) {
        if (document.title != currTitle) {
            console.log("updateTitle function called.");
            if (node == undefined) {
                node = document.getElementById("primary-inner");
            };
            setTimeout(function () { // wait a little in case title changes before the node reloads
                let channelName = node.children[7].children[1].children[0].children[0].children[0].children[0].children[1].children[0].children[0].children[0].children[0].children[0].innerHTML;
                document.title += " - " + channelName;
                currTitle = document.title;
            }, 500);
        };
    };
    
    let nodeLoaded = setInterval(function () {
        // update title on page load
        let node = document.getElementById("primary-inner");
        if (node != undefined) {
            updateTitle(node);
            clearInterval(nodeLoaded);
        };
    }, 500);
    
    // listen for future changes
    new MutationObserver(function (mutations) {
        updateTitle(undefined);
    }).observe(
        document.querySelector("title"),
        { subtree: true, characterData: true, childList: true }
    );