Reputation: 4406
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
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