使用Youtube的javascript API和jQuery

我目前正在尝试使用YouTube API作为jQuery插件的一部分,我遇到了一些问题。

YT api的工作方式是加载flash播放器,当它准备就绪时,它会发回一个名为onYouTubePlayerReady(playerId)的全局函数。 然后,您可以将该id与getElementById(playerId)结合使用,将javascript调用发送到Flash播放器(即player.playVideo(); )。

您可以使用player.addEventListener('onStateChange', 'playerState');将事件监听器附加到播放器player.addEventListener('onStateChange', 'playerState'); 它会将任何状态更改发送到另一个全局函数(在本例中为playerState )。

问题是我不确定如何将状态变化与特定玩家联系起来。 我的jQuery插件可以愉快地将多个video附加到选择器并将事件附加到每个video,但是当状态实际发生变化时,我会忘记它发生在哪个播放器中。

我希望一些示例代码可以使事情更清晰一些。 以下代码应该可以在任何html文件中正常工作。

     Sandbox    google.load("jquery", "1.3.2"); google.load("jqueryui", "1.7.0");    (function($) { $.fn.simplified = function() { return this.each(function(i) { var params = { allowScriptAccess: "always" }; var atts = { id: "ytplayer"+i }; $div = $('
').attr('id', "containerplayer"+i); swfobject.embedSWF("http://www.youtube.com/v/QTQfGd3G6dg&enablejsapi=1&playerapiid=ytplayer"+i, "containerplayer"+i, "425", "356", "8", null, null, params, atts); $(this).append($div); }); } })(jQuery); function onYouTubePlayerReady(playerId) { var player = $('#'+playerId)[0]; player.addEventListener('onStateChange', 'playerState'); } function playerState(state) { console.log(state); } $(document).ready(function() { $('.secondary').simplified(); });

您将看到有关状态更改的console.log()outputtin信息,但是,就像我说的,我不知道如何判断它与哪个玩家相关联。

有没有人想过这个方法呢?

编辑:对不起,我还应该提到我已经尝试在闭包中包装事件调用。

 function onYouTubePlayerReady(playerId) { var player = $('#'+playerId)[0]; player.addEventListener('onStateChange', function(state) { return playerState(state, playerId, player); } ); } function playerState(state, playerId, player) { console.log(state); console.log(playerId); } 

在这种情况下, playerState永远不会被调用。 这更令人沮丧。

编辑:

显然在player对象上调用addEventListener会导致脚本被用作传递给flash对象的XML属性中的字符串 – 这会排除闭包等等,所以现在是时候了解一个老派丑陋的黑客:

 function onYouTubePlayerReady(playerId) { var player = $('#'+playerId)[0]; player.addEventListener('onStateChange', '(function(state) { return playerState(state, "' + playerId + '"); })' ); } function playerState(state, playerId) { console.log(state); console.log(playerId); } 

经过测试和工作!

我正在使用Jquery SWFobject插件, SWFobject

在video结尾添加&enablejsapi = 1非常重要

HTML:

 

jQuery的:

  $('#embedSWF').flash({ swf: 'http://www.youtube.com/watch/v/siBoLc9vxac', params: { allowScriptAccess: "always"}, flashvars: {enablejsapi: '1', autoplay: '0', allowScriptAccess: "always", id: 'ytPlayer' }, height: 450, width: 385 }); function onYouTubePlayerReady(playerId) { $('#embedSWF').flash(function(){this.addEventListener("onStateChange", "onPlayerStateChange")}); } function onPlayerStateChange(newState) { alert(newState); } 

onYouTubePlayerReady必须在$(document).ready(function()之外才能被触发

我有同样的问题并尝试了接受的答案。 这对我不起作用; 从未调用过playerState()函数。 但是,它让我走上了正确的道路。 我最终做的是这样的:

 // Within my mediaController "class" window["dynamicYouTubeEventHandler" + playerID] = function(state) { onYouTubePlayerStateChange(state, playerID); } embedElement.addEventListener("onStateChange", "dynamicYouTubeEventHandler" + playerID); // End mediaController class // Global YouTube event handler function onYouTubePlayerStateChange(state, playerID) { var mediaController = GetMediaControllerFromYouTubeEmbedID(playerID); mediaController.OnYouTubePlayerStateChange(state); } 

这是相当讨厌的,但YouTube JavaScript API的当前状态也是如此。


如果您使用任何类型的高级原型模式,这里有一些其他有用/讨厌的代码。 这基本上允许您从YouTube播放器ID中检索“类”实例:

 // Within my mediaController "class" // The containerJQElement is the jQuery wrapped parent element of the player ID // Its ID is the same as the player ID minus "YouTubeEmbed". var _self = this; containerJQElement.data('mediaController', _self); // End mediaController class // Global YouTube specific functions function GetMediaControllerFromYouTubeEmbedID(embedID) { var containerID = embedID.replace('YouTubeEmbed', ''); var containerJQObject = $("#" + containerID); return containerJQObject.data('mediaController'); } function onYouTubePlayerReady(playerId) { var mediaController = GetMediaControllerFromYouTubeEmbedID(playerId); mediaController.OnYouTubeAPIReady(); } 

这是一篇很好的文章,通过创建一个包装单个玩家的类,包括使用与前一个答案中提到的方法类似的方法将事件分派给单个对象。

http://blog.jcoglan.com/2008/05/22/dispatching-youtube-api-events-to-individual-javascript-objects/

这样的事情怎么样:

 var closureFaker = function (func, scope) { var functionName = 'closureFake_' + (((1+Math.random())*0x10000000)|0).toString(16); window[functionName] = function () { func.apply(scope || window, arguments); }; console.log('created function:', functionName, window[functionName]); return functionName; }; ytplayer.addEventListener("onStateChange", closureFaker(function () { //place your logic here console.log('state change', arguments) }));