Thomas Kekeisen
Thomas Kekeisen

Reputation: 4406

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?

Upvotes: 2

Views: 1231

Answers (1)

Brock Adams
Brock Adams

Reputation: 93533

"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);
}

Upvotes: 7

Related Questions