问题
I hava a single HTML with many youtube players.
I'm suscribing to the onStateChange to get notified when the user plays a video.
function onYouTubePlayerReady(playerid) {
var player = document.getElementById("playerA");
player.addEventListener("onStateChange", "callback");
}
Now the callback get the newState as parameter.
function callback(newState) {
...
}
This works ok with only one player. But with many players, how can I know wich player raised the StateChange event? Callback just have one parameter.
Is there a way to know which player raised the event form callback or i have to set uo a diferent callback for each one?
回答1:
Here is my solution based on the other answers:
(1) Add id
parameter to the object and/or embed tags
(2) Add playerapiid parameter to video urls (it should match the id
)
<object id="video1" data="http://www.youtube.com/v/AAAAAAAAAAA&version=3&enablejsapi=1&playerapiid=video1" ...>
<embed ...>
</object>
<object id="video2" data="http://www.youtube.com/v/BBBBBBBBBBB&version=3&enablejsapi=1&playerapiid=video2" ...>
<embed ...>
</object>
(3) Create named callback functions for each video and assign them to the player in the onYouTubePlayerReady
event. Here is one way of doing it:
function onYouTubePlayerReady(playerApiId) {
var player = document.getElementById(playerApiId);
window["onStateChange" + playerApiId] = function(state) {
console.log("#" + playerApiId + ": new state " + state);
};
player.addEventListener("onStateChange", "onStateChange" + playerApiId);
}
I have published a demo here.
回答2:
I had this exact same problem. Here's my solution:
var videos = {};
//store the video player's data in the hash, with the playerapiid as the key
function loadFeaturedVideo(youTubeVideoId) {
videos["featuredytplayer"] = {
"yt_id": youTubeVideoId,
"wrapperSelector": "#featured_player_wrapper",
"embed": "featuredYtPlayer"
};
...
}
function onYouTubePlayerReady(playerId) {
var currentVideo = videos[playerId];
var ytPlayer = document.getElementById(currentVideo["embed"]);
videos[playerId]["stateChangeListener"] = function(newState) {
var container = $(currentVideo["wrapperSelector"]);
...
}
ytPlayer.addEventListener("onStateChange", "videos['" + playerId + "']['stateChangeListener']");
...
}
Then you can just access whatever variables you want via the closure. Ideally, we could just use an anonymous function in addEventListener(), but due to limitations in the ActionScript/Javascript bridge, that's not possible.
Inspired by this discussion: http://groups.google.com/group/youtube-api-gdata/browse_thread/thread/e8a8c85b801b9e25
回答3:
@alalonde's solution doesn't work anymore because Adobe imposed additional restrictions on the characters that can be used for Flash event listeners. You can no longer use [] or (), which makes the previous solutions regarding this issue obsolete. Those characters will generate the following javascript error:
identifier starts immediately after numeric literal
Here's my solution (using period characters):
var players = {}; // global to keep track of all players on the page
function onYouTubePlayerReady (idPlayer) {
var ytPlayer = document.getElementById (idPlayer);
var idPlayerParams = 'yt' + Math.floor (Math.random()*100000); // create random varable name
players [idPlayerParams] = {
idPlayer: idPlayer,
onStateChanged: function (state) {
alert ('youtube player state changed to: ' + state + ', player id: ' + idPlayer);
},
onError: function (err) {
alert ('youtube player error: ' + err + ', player id: ' + idPlayer);
}
};
ytPlayer.addEventListener ('onStateChange', 'players.' + idPlayerParams + '.onStateChanged');
ytPlayer.addEventListener ('onError', 'players.' + idPlayerParams + '.onError');
}
来源:https://stackoverflow.com/questions/4718404/retrieve-player-state-with-multiple-youtube-players-on-a-page