Liens Fiddle: Code source - Aperçu - Petite version
Mise à jour: Cette petite fonction n'exécutera du code que dans un seul sens. Si vous voulez une prise en charge complète (par exemple, les écouteurs / getters d'événements), jetez un œil à Listening for Youtube Event dans jQuery
À la suite d'une analyse approfondie du code, j'ai créé une fonction: function callPlayer
demande un appel de fonction sur n'importe quelle vidéo YouTube encadrée. Consultez la référence YouTube Api pour obtenir une liste complète des appels de fonction possibles. Lisez les commentaires sur le code source pour une explication.
Le 17 mai 2012, la taille du code a été doublée afin de prendre en charge l'état prêt du joueur. Si vous avez besoin d'une fonction compacte qui ne traite pas l'état prêt du lecteur, consultez http://jsfiddle.net/8R5y6/ .
/**
* @author Rob W <gwnRob@gmail.com>
* @website https://stackoverflow.com/a/7513356/938089
* @version 20190409
* @description Executes function on a framed YouTube video (see website link)
* For a full list of possible functions, see:
* https://developers.google.com/youtube/js_api_reference
* @param String frame_id The id of (the div containing) the frame
* @param String func Desired function to call, eg. "playVideo"
* (Function) Function to call when the player is ready.
* @param Array args (optional) List of arguments to pass to function func*/
function callPlayer(frame_id, func, args) {
if (window.jQuery && frame_id instanceof jQuery) frame_id = frame_id.get(0).id;
var iframe = document.getElementById(frame_id);
if (iframe && iframe.tagName.toUpperCase() != 'IFRAME') {
iframe = iframe.getElementsByTagName('iframe')[0];
}
// When the player is not ready yet, add the event to a queue
// Each frame_id is associated with an own queue.
// Each queue has three possible states:
// undefined = uninitialised / array = queue / .ready=true = ready
if (!callPlayer.queue) callPlayer.queue = {};
var queue = callPlayer.queue[frame_id],
domReady = document.readyState == 'complete';
if (domReady && !iframe) {
// DOM is ready and iframe does not exist. Log a message
window.console && console.log('callPlayer: Frame not found; id=' + frame_id);
if (queue) clearInterval(queue.poller);
} else if (func === 'listening') {
// Sending the "listener" message to the frame, to request status updates
if (iframe && iframe.contentWindow) {
func = '{"event":"listening","id":' + JSON.stringify(''+frame_id) + '}';
iframe.contentWindow.postMessage(func, '*');
}
} else if ((!queue || !queue.ready) && (
!domReady ||
iframe && !iframe.contentWindow ||
typeof func === 'function')) {
if (!queue) queue = callPlayer.queue[frame_id] = [];
queue.push([func, args]);
if (!('poller' in queue)) {
// keep polling until the document and frame is ready
queue.poller = setInterval(function() {
callPlayer(frame_id, 'listening');
}, 250);
// Add a global "message" event listener, to catch status updates:
messageEvent(1, function runOnceReady(e) {
if (!iframe) {
iframe = document.getElementById(frame_id);
if (!iframe) return;
if (iframe.tagName.toUpperCase() != 'IFRAME') {
iframe = iframe.getElementsByTagName('iframe')[0];
if (!iframe) return;
}
}
if (e.source === iframe.contentWindow) {
// Assume that the player is ready if we receive a
// message from the iframe
clearInterval(queue.poller);
queue.ready = true;
messageEvent(0, runOnceReady);
// .. and release the queue:
while (tmp = queue.shift()) {
callPlayer(frame_id, tmp[0], tmp[1]);
}
}
}, false);
}
} else if (iframe && iframe.contentWindow) {
// When a function is supplied, just call it (like "onYouTubePlayerReady")
if (func.call) return func();
// Frame exists, send message
iframe.contentWindow.postMessage(JSON.stringify({
"event": "command",
"func": func,
"args": args || [],
"id": frame_id
}), "*");
}
/* IE8 does not support addEventListener... */
function messageEvent(add, listener) {
var w3 = add ? window.addEventListener : window.removeEventListener;
w3 ?
w3('message', listener, !1)
:
(add ? window.attachEvent : window.detachEvent)('onmessage', listener);
}
}
Usage:
callPlayer("whateverID", function() {
// This function runs once the player is ready ("onYouTubePlayerReady")
callPlayer("whateverID", "playVideo");
});
// When the player is not ready yet, the function will be queued.
// When the iframe cannot be found, a message is logged in the console.
callPlayer("whateverID", "playVideo");
Questions (et réponses) possibles:
Q : Cela ne fonctionne pas!
R : «Ne fonctionne pas» n'est pas une description claire. Recevez-vous des messages d'erreur? Veuillez montrer le code correspondant.
Q : playVideo
ne lit pas la vidéo.
R : La lecture nécessite une interaction de l'utilisateur et la présence de allow="autoplay"
sur l'iframe. Voir https://developers.google.com/web/updates/2017/09/autoplay-policy-changes et https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide
Q : J'ai intégré une vidéo YouTube en utilisant <iframe src="http://www.youtube.com/embed/As2rZGPGKDY" />
mais la fonction n'exécute aucune fonction!
A : Vous devez ajouter ?enablejsapi=1
à la fin de votre URL: /embed/vid_id?enablejsapi=1
.
Q : J'obtiens le message d'erreur "Une chaîne non valide ou illégale a été spécifiée". Pourquoi?
R : L'API ne fonctionne pas correctement sur un hôte local (file://
). Hébergez votre page (de test) en ligne ou utilisez JSFiddle . Exemples: voir les liens en haut de cette réponse.
Q : Comment le saviez-vous?
R : J'ai passé un certain temps à interpréter manuellement la source de l'API. J'ai conclu que je devais utiliser lepostMessage
méthode. Pour savoir quels arguments passer, j'ai créé une extension Chrome qui intercepte les messages. Le code source de l'extension peut être téléchargé ici .
Q : Quels navigateurs sont pris en charge?
R : Tous les navigateurs prenant en charge JSON etpostMessage
.
- IE 8+
- Firefox 3.6+ (en fait 3.5, mais a
document.readyState
été implémenté dans 3.6)
- Opera 10.50+
- Safari 4+
- Chrome 3+
Réponse / implémentation associée: Fade-in a frame video using jQuery
Full API support: Listening for Youtube Event in jQuery
Official API: https://developers.google.com/youtube/iframe_api_reference
Historique des révisions
- 17 mai 2012
Mise en œuvre onYouTubePlayerReady
: callPlayer('frame_id', function() { ... })
.
Les fonctions sont automatiquement mises en file d'attente lorsque le lecteur n'est pas encore prêt.
- 24 juillet 2012
Mis à jour et testé avec succès dans les navigateurs pris en charge (à venir).
- 10 octobre 2013 Lorsqu'une fonction est passée en argument,
callPlayer
force un contrôle de disponibilité. Cela est nécessaire, car quand callPlayer
est appelé juste après l'insertion de l'iframe alors que le document est prêt, il ne peut pas savoir avec certitude que l'iframe est entièrement prêt. Dans Internet Explorer et Firefox, ce scénario a entraîné une invocation trop précoce depostMessage
, qui a été ignoré.
- 12 décembre 2013, recommandé d'ajouter
&origin=*
l'URL.
- 2 mars 2014, retrait
&origin=*
de la recommandation de suppression de l'URL.
- 9 avril 2019, correction d'un bug qui entraînait une récursivité infinie lorsque YouTube se charge avant que la page ne soit prête. Ajoutez une note sur la lecture automatique.