Search code examples
javascriptyoutube-apigreasemonkeyuserscripts

How to call Youtube-Flash-API of existing Videos using Greasemonkey


I want to write a Greasemonkey script to detect when a YouTube video on a website starts playing to stop my winamp playing music. Everything works fine, my script detects the video, enables the API and also the onYouTubePlayerReady event gets called. But I have no idea how to register the onStateChange callback, this is my code:

unsafeWindow.onYouTubePlayerReady = function (playerId)
{
    alert('Visible');

    document.getElementById(playerId).addEventListener('onStateChange', 'stateChanged');    

    alert('Not visible, so the line above crashes');
}

unsafeWindow.stateChanged = function (state)
{
    alert('never called, too');
}

Is there a solution for this problem or is it just impossible?


Solution

  • "the problem is just the listener on "onStateChange" "

    Okay, in order to get around some scoping problems, it's best just to inject code that interacts with the YouTube API.

    The following works in Firefox+Greasemonkey, and in Chrome or Chrome+Tampermonkey. It should also work on any browser that supports userscripts:

    function GM_main () {
        window.stateChanged = function (state) {
            console.log ('GM: In stateChanged().  State = ', state);
        }
    
        window.onYouTubePlayerReady = function (playerId) {
            /*-- playerId is not being set by Youtube. Use
                hard-coded id (movie_player) instead.
            */
            var playerNode  = document.getElementById ("movie_player");
            if (playerNode) {
                /*--- Note, inside onYouTubePlayerReady ONLY, the YouTube API
                    seems to override addEventListener. Hence the nonstandard
                    parameters.
                */
                playerNode.addEventListener ('onStateChange', 'stateChanged');
    
                console.log ('GM: Listener installed just fine.');
            }
            else
                console.error ("GM: Player node not found!");
        }
    }
    
    addJS_Node (null, null, GM_main);
    
    function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
        var D                                   = document;
        var scriptNode                          = D.createElement ('script');
        if (runOnLoad) {
            scriptNode.addEventListener ("load", runOnLoad, false);
        }
        scriptNode.type                         = "text/javascript";
        if (text)       scriptNode.textContent  = text;
        if (s_URL)      scriptNode.src          = s_URL;
        if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';
    
        var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
        targ.appendChild (scriptNode);
    }