Quiero ser capaz de controlar iframe basados en YouTube los jugadores. Los jugadores ya estará en el HTML, pero quiero el control de ellos a través de la API de JavaScript.

He estado leyendo el documentación para el iframe de la API que explican cómo agregar un nuevo video a la página de la API, y a continuación, el control es con el reproductor de YouTube funciones:

var player;
function onYouTubePlayerAPIReady() {
    player = new YT.Player('container', {
        height: '390',
        width: '640',
        videoId: 'u1zgFlCw8Aw',
        events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
        }
    });
}

Que el código que se crea un nuevo reproductor de objeto y se asigna a ‘el jugador’, a continuación, inserta dentro de la #div contenedor. Entonces me pueden operar en ‘jugador’ y llamar a playVideo(), pauseVideo(), etc. en él.

Pero quiero ser capaz de operar en iframe los jugadores que ya están en la página.

Yo podría hacer esto muy fácilmente con el viejo método de inserción, con algo como:

player = getElementById('whateverID');
player.playVideo();

Pero esto no funciona con la nueva iframes. ¿Cómo puedo asignar un objeto iframe ya en la página y, a continuación, utilizar las funciones de la API en él?

4 Comentarios

  1. 305

    El Violín Enlaces: Código fuenteVista previaVersión pequeña

    Actualización: Esta pequeña función sólo ejecutar código en una sola dirección. Si desea soporte completo (por ejemplo, detectores de eventos /getters), tiene una mirada en Escuchando por Youtube Evento en jQuery

    Como resultado de un profundo análisis de código, he creado una función: function callPlayer solicita una llamada de función en cualquier enmarcada vídeo de YouTube. Ver el Referencia de la Api de YouTube para obtener una lista completa de posibles llamadas de función. Leer los comentarios en el código fuente de una explicación.

    El 17 de mayo de 2012, el código de tamaño se duplicó en el fin de cuidar el jugador del estado de listo. Si usted necesita un compacto, función que no se ocupa de que el jugador del estado de listo, ver http://jsfiddle.net/8R5y6/.

    /**
    * @author       Rob W <[email protected]>
    * @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);
    }
    }

    Uso:

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

    Posibles preguntas (& respuestas):

    Q: no funciona!

    Un: «no funciona» no es una descripción clara. ¿Te da algún mensaje de error? Por favor, mostrar el código correspondiente.

    Q: playVideo no se reproduce el video.

    Un: Reproducción requiere la interacción del usuario, y la presencia de allow="autoplay" en el iframe. Ver https://developers.google.com/web/updates/2017/09/autoplay-policy-changes y https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide

    Q: he incrustado un vídeo de YouTube usando <iframe src="http://www.youtube.com/embed/As2rZGPGKDY" />pero la función no se ejecuta ninguna función!

    Un: Usted tiene que agregar ?enablejsapi=1 al final de la dirección URL: /embed/vid_id?enablejsapi=1.

    Q: obtengo un mensaje de error «es inválida o ilegal de la cadena se ha especificado». Por qué?

    Un: La API de no funcionar correctamente en un host local (file://). Alojar su página (de prueba) en línea, o el uso JSFiddle. Ejemplos: Consulte los vínculos en la parte superior de esta respuesta.

    Q: ¿Cómo sabes esto?

    Un: me he pasado algún tiempo manualmente interpretar la API de origen. Llegué a la conclusión de que había que usar la postMessage método. Para saber cuáles son los argumentos que pasar, he creado una extensión de Chrome que intercepta los mensajes. El código fuente de la extensión puede ser descargado aquí.

    Q: ¿Qué navegadores son compatibles?

    Un: Cada navegador que soporta JSON y postMessage.

    • IE 8+
    • Firefox 3.6+ (en realidad 3.5, pero document.readyState fue implementado en 3.6)
    • Opera 10.50+
    • Safari 4+
    • Chrome 3+

    Relacionados con la respuesta /aplicación: Fade-en una trama de vídeo usando jQuery

    Completo soporte de API: Escuchando por Youtube Evento en jQuery

    Oficial de la API: https://developers.google.com/youtube/iframe_api_reference

    Revisión de la historia

    • 17 de mayo de 2012

      Implementado onYouTubePlayerReady: callPlayer('frame_id', function() { ... }).

      Las funciones son automáticamente en la cola cuando el jugador no está listo todavía.
    • 24 de julio de 2012

      Actualizado y successully probado en los navegadores compatibles (mirar hacia adelante).
    • 10 de octubre de 2013
      Cuando una función se le pasa como argumento, callPlayer las fuerzas de la verificación de la preparación. Esto es necesario, porque cuando callPlayer es llamado justo después de la inserción del iframe, mientras que el documento está listo, no se puede saber con certeza que el iframe es totalmente listo. En Internet Explorer y Firefox, esta situación se tradujo en una edad demasiado temprana invocación de postMessage, que fue ignorada.
    • 12 de diciembre de 2013, se recomienda agregar el &origin=* en la URL.
    • 2 Mar 2014, se retractó de recomendación para quitar &origin=* a la dirección URL.
    • 9 de abril de 2019, corregir el error que resultó en una recursión infinita cuando YouTube se carga antes de que la página estaba listo. Agregar una nota sobre la reproducción automática.
    • Traté de que en realidad. Parece que el JSON en el error no es el que está en su guión, pero dentro del iframe como parte de youtube API.
    • gracias por este buen fragmento de código. Has encontrado alguna manera de usar el Evento de Mensaje en lugar de utilizar el youtube API de JS con el fin de añadir un detector de eventos?
    • El PostMessage método se basa en el YT API de JS (?enablejsapi=1). Sin habilitar la API de JS, el postMessage método de no hacer nada, Ver la vinculado respuesta para una fácil implementación de detectores de eventos. También he creado, pero no se publican, código legible para comunicarse con el marco. Decidí no publicarlo, porque su efecto es similar a la de YouTube predeterminados Marco de la API.
    • Nota: Este método no funciona en <IE7, debido a la falta de soporte para postMessage (también, JSON nativo no es compatible, pero eso es menos importante, ya que puede ser implementado usando json2.js) – Ver esta pregunta: Detener el reproductor de Youtube en IE7
    • ¿Alguien tiene alguna idea de por qué el window.onload evento no funciona en webkit? La demo (y mis propias pruebas) reproducción automática en Firefox, pero no en Chrome o Safari. El botón de enlaces para reproducir, pausar, etc hacer el trabajo, sin embargo.
    • Me las arreglé para conseguir la reproducción automática para el trabajo mediante la adición de un setTimeout() contenedor, pero esto es realmente una hacky solución. Alguien tiene algo mejor? (Aquí hay una bifurcación de la demo original con la corrección: jsfiddle.net/LMqL9)
    • He actualizado el método para que automáticamente se encarga de que el jugador del estado de listo. callPlayer("whateverID", "playVideo") ahora se ejecuta la función cuando el jugador está listo. Otro método: callPlayer("whateverID", function() {callPlayer('whateverID', 'playVideo');});.
    • Que se ha solucionado el problema, gracias! Al final he usado el código de esta pregunta, porque necesitaba un par de detectores de eventos: stackoverflow.com/questions/7988476/…
    • Esto no funciona en cualquier navegador. Incluso el Jsfiddle no funciona. Chrome muestra este error: JavaScript de seguridad intento de acceso a marco con la dirección URL jsfiddle.net/hrVcy de marco con la dirección URL youtube.com/embed/u1zgFlCw8Aw?enablejsapi=1. Dominios, protocolos y puertos deben coincidir.
    • Revisado y probado el código en todos los listados de los navegadores – consulte jsfiddle.net/g6P5H (la versión lite, que no de la cola de eventos no ha cambiado, debido a que aún funcionaba bien: jsfiddle.net/8R5y6).
    • Off Topic: a partir De un nombre similar amigo que mantiene el Drupal Medios de comunicación: Youtube módulo, nuestros usuarios gracias.
    • increíble trabajo! Me las arreglé para hacerlo perfectamente obras para la función no devuelve ningún valor. Ahora estoy preguntando cómo obtener el resultado de una función como «getCurrentTime»? Gracias!
    • Realmente brillante. Usando algo similar, es posible detectar cuando el video ha terminado?
    • Que requiere de la escucha para el evento message y analizar el estado del resultado. Esto no es tan fácil como simples llamadas como playVideo, por lo que recomiendo el uso de la API oficial para que. Consulte developers.google.com/youtube/iframe_api_reference#Events.
    • Yo estoy a envolver mi llamada inicial (por ejemplo, para silenciar) en un tiempo de espera de bloque. No estoy seguro si hay una condición de carrera aquí en algún lugar. Yo era incapaz de reproducir usando una simple JS Violín ejemplo, sin embargo. Es alguien más teniendo problemas similares?
    • Este parece que no funciona (probado la jsfiddle página en el PC: Chrome, FF, IE y 11, que en realidad se estrelló en la carga, Mac: Chrome). Alguna idea de cómo hacer que esto funcione de nuevo? No JS errores por el camino, simplemente no responde a reproducir/pausa/parada de comandos.
    • A mi me funciona en Cromo 31, jsfiddle.net/g6P5H/214/show. ¿Anexar &origin=* para el jugador URL?
    • Yo no la prueba de Cromo. Sin embargo, si se produce un bloqueo cuando no hay &origen=* es apenas algo estoy inclinado a usar… no se Puede decir realmente el cliente: «oye, no es mi culpa que tus clientes navegador se bloquea, no anexar &origen=* a su url de youtube…»
    • Hey @RobW, cuando tengas tiempo, puedes buscar en mi pregunta demasiado? stackoverflow.com/questions/22854231/…
    • lo bonita respuesta! @Rob W por cierto, funciona como playVideo(). pauseVideo etc no toma ningún parámetro, cómo hacerlo si queremos usar funciones como loadVideoById(«bHQqvYy5KYo», 5, «grande») ? ¿acabo de poner todo lo que la sintaxis como un ‘func’ parámetro?
    • W en realidad, la función que voy a usar es cuePlaylist(String o Array …etc).. que es donde estoy atascado, así que estoy confundido en cómo pasar de la matriz a la ‘args’ en su CallPlayer función… por ejemplo para cuePlaylist, necesito 4 parámetros: matriz de Cadena, un Número, un Número,una Cadena.. ¿solo necesito un empujón que 4 parámetros para el parámetro ‘args’ en su CallPlayer función? (ps: lo siento, estoy realmente débil en javascript, voy a llamar a la función desde java android) y gracias por responder
    • Sí, usted necesita para poner estos 4 argumentos en la matriz: callPlayer('whateverID', 'funcname', ['arg1', 'arg2', 'arg3', 'etc']);
    • W hi rob perdona que te moleste una vez más, así que tengo esta sintaxis: var args = «[[‘8N-K4lcI7Jg’,’cu4uF6XVnO8′,’p0jPtpCgsRw’],1,0,’highres’]»; y que yo llamo callPlayer(«contenedor», «cuePlaylist», args); pero el jugador no cue los videos, me puedes ayudar a rob?
    • W ah lo siento es una mala sintaxis he utilizado, que se detectó la args como cadena no de la matriz jaja.. ahora es la formación de colas de la lista de reproducción, pero el jugador dijo parámetro no válido.. ¿qué hice mal? así que he enumerado 4 parámetro para cuePlaylist(String o Array,Número,Número,una Cadena), pero me dice parámetro no válido
    • voy a llamar a callPlayer(‘contenedor’,’cuePlaylist’,[[‘id1′,’id2′,’id3′],1,0,’highres’]); » ¿hice algo mal en la sintaxis?
    • No veo ningún error evidente. Por favor, hacer una nueva pregunta con un sistema autónomo de pasos-para-reproducir en lugar de añadir preguntas en los comentarios a esta respuesta.
    • ah ahora es el trabajo! me envolvió la [] dentro de » lo que el código javascript de leer una cadena en lugar de la matriz. mi mala jaja, muchas gracias por tu ayuda @Rob W , este es un gran código de usted
    • Usted puede hacer esto con mucho menos código: jsfiddle.net/kmturley/g6P5H/296
    • He tenido que cambiar de domReady a domReady = document.readyState == 'complete' || document.readyState == 'interactive'. De lo contrario sería congelar la página en algunos situtations en un bucle sin fin. No he probado completamente este cambio, pero hasta ahora parece funcionar en una variedad de situaciones.
    • excelente respuesta amigo. le conozco la respuesta a mi reciente de youtube javascript pregunta?: stackoverflow.com/questions/37724246/get-youtube-playlist-index
    • No quiero ser grosero, pero nadie tiene una versión que no necesita agregar javascript dentro de la a href y el uso de un selector de consultas o puede crear botón de control de la mosca de la
    • Os adjunto el código como un archivo, y luego trató de llamarlo como función onYouTubeIframeAPIReady() { $(‘.playerLocation’).en(‘mouseover’,function(){ callPlayer(«youtube-video», function() { // Esta función se ejecuta cuando el jugador esté listo («onYouTubePlayerReady») callPlayer(«youtube-video», «playVideo»); }); }); } pero me sale el error no capturado ReferenceError: callPlayer no está definido

  2. 31

    Parece que YouTube ha actualizado su API de JS, así que esto es disponible por defecto! Usted puede utilizar una existente YouTube iframe ID…

    <iframe id="player" src="http://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1&origin=http://example.com" frameborder="0"></iframe>

    …en tu JS…

    var player;
    function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
    events: {
    'onStateChange': onPlayerStateChange
    }
    });
    }
    function onPlayerStateChange() {
    //...
    }

    …y el constructor va a utilizar el existente iframe en lugar de reemplazarlo con uno nuevo. Esto también significa que usted no tiene que especificar el videoId para el constructor.

    Ver La carga de un reproductor de vídeo

    • te estás perdiendo el autoplay=1 parámetro en la url. En su dirección url de ejemplo, sería youtube.com/embed/M7lc1UVf-VE?enablejsapi=1& autoplay=1 &origen=example.com
    • él no quiere usar la reproducción automática de los parámetros de url. En su lugar, él intenta iniciar el vídeo mediante el uso de la js-Api función de autoplay. Pero por alguna razón la onYouTubeIframeAPIReady() la función no se invoca.
    • Me lo imaginé. 1) eliminar el &origin=example.com a partir de la url del iframe. 2) en la «Marcos & Extensiones» de la sección de su jsfiddle el segundo menú desplegable para «No envuelva en – <head>» 3) agregar el iframe de youtube api como recurso externo (youtube.com/iframe_api); I bifurcada su violín y aplicar estos cambios: jsfiddle.net/e97famd1/1
    • Alguna idea de lo que event o command para enviar a la YT iframe para detener listening para el estado?
    • Me sale este error: Uncaught (en promesa) DOMException: La play() solicitud fue interrumpida por una llamada para hacer una pausa(). Promesa (async) (anónimo) @ scripts.js:20 despacho @ jquery-1.12.4.js:5226 elemData.asa @ jquery-1.12.4.js:4878 cast_sender.js:67 Uncaught DOMException: no se pudo construir ‘PresentationRequest’: Presentación de un documento inseguro [cast:233637DE?capabilities=video_out%2Caudio_out&clientId=153262711713390989&autoJoinPolicy=tab_and_origin_scoped&defaultActionPolicy=cast_this_tab&launchTimeout=30000] está prohibido de un seguro de contexto.
    • Me lo imaginé. Tuve que iniciar jugadores diferentes. Gracias por su respuesta!
    • usted puede agregar una lista de playerVars para conseguir que la reproducción automática player = new YT.Player('player', { 'playerVars': { 'autoplay': 0, 'controls': 0, }, events: { 'onStateChange': onPlayerStateChange } }); developers.google.com/youtube/…

  3. 17

    Usted puede hacer esto con mucho menos código:

    function callPlayer(func, args) {
    var i = 0,
    iframes = document.getElementsByTagName('iframe'),
    src = '';
    for (i = 0; i < iframes.length; i += 1) {
    src = iframes[i].getAttribute('src');
    if (src && src.indexOf('youtube.com/embed') !== -1) {
    iframes[i].contentWindow.postMessage(JSON.stringify({
    'event': 'command',
    'func': func,
    'args': args || []
    }), '*');
    }
    }
    }

    De trabajo ejemplo:
    http://jsfiddle.net/kmturley/g6P5H/296/

    • Realmente me gustó de este modo, está adaptado para trabajar con un Angular de la directiva, así que no necesitan todo el circuito y pasar el func dependiendo de la función de conmutación con el alcance (básicamente, si el video se muestra -> reproducción automática; else -> pausar el video). Gracias!
    • Usted debe compartir la directiva, podría ser útil!
    • Aquí es una adaptación del código de un Bolígrafo: codepen.io/anon/pen/qERdza espero que te ayude! También se alterna presionando la tecla ESC cuando tienes el video en
    • Esto parece demasiado bueno para ser verdad! Hay algún navegador/limitaciones de seguridad para el uso de este método?
    • Sí, es decir, tiene un par de limitaciones, especialmente IE10 que apoya MessageChannel en lugar de postMessage: caniuse.com/#search=postMessage también ser conscientes de cualquier Contenido de las Políticas de Seguridad también restringir el uso de esta función
    • Cómo sabemos que youtube es el juego? cualquier devolución de llamada desde el iframe de youtube, por lo que fuera, puede suscribirse?
    • Mejor respuesta hasta ahora. Gracias. Se puede mostrar cómo agregar el botón pantalla completa?
    • Este juegos/paradas de cada vídeo de youtube en la página al mismo tiempo.
    • Sí, usted puede modificar para llamar a un solo jugador, por ejemplo, por identificación: documento.getElementById(‘myvideo1’).contentWindow.postMessage(JSON.stringify({ ‘evento’: ‘comando’, ‘func’: func, ‘args’: args|| [] }), ‘*’);

  4. 4

    Mi propia versión de Kim T del código anterior, que se combina con algo de jQuery y permite la focalización de los específicos de iframes.

    $(function() {
    callPlayer($('#iframe')[0], 'unMute');
    });
    function callPlayer(iframe, func, args) {
    if ( iframe.src.indexOf('youtube.com/embed') !== -1) {
    iframe.contentWindow.postMessage( JSON.stringify({
    'event': 'command',
    'func': func,
    'args': args || []
    } ), '*');
    }
    }

Dejar respuesta

Please enter your comment!
Please enter your name here