Прослушивание событий Youtube в JavaScript или jQuery - PullRequest
19 голосов
/ 03 ноября 2011

У меня есть слайдер, который включает 4 видео на YouTube, которые встроены с помощью встроенного кода iframe

http://www.youtube.com/embed/'.$i.'?enablejsapi=1

Я пытаюсь заставить событие onStateChange любого из четырех видео вызвать функцию, которую я назвал stopCycle(), которая остановит слайдер, когда видео начнет воспроизводиться. У iframes нет идентификатора. Я не уверен, как правильно запечатлеть это событие, и мог бы посоветовать, что я делаю неправильно.

<script charset="utf-8" type="text/javascript" src="http://www.youtube.com/player_api"></script>

var playerObj = document.getElementById("tab2"); // the container for 1 of the 4 iframes

playerObj.addEventListener("onStateChange", "stopCycle");

function stopCycle(event) {
    alert('Stopped!');
}

Ответы [ 4 ]

41 голосов
/ 03 ноября 2011

API кадров YouTube поддерживает поддержку существующих кадров . Чтобы улучшить использование, я создал несколько вспомогательных функций. Посмотрите на код + комментарии ниже и демо: http://jsfiddle.net/YzvXa/197

Чтобы связать функции с существующими кадрами, вам необходимо передать идентификационную ссылку на кадр. В вашем случае фрейм содержится в контейнере с id="tab2". Я определил пользовательскую функцию для более легкой реализации:

function getFrameID(id){
    var elem = document.getElementById(id);
    if (elem) {
        if(/^iframe$/i.test(elem.tagName)) return id; //Frame, OK
        // else: Look for frame
        var elems = elem.getElementsByTagName("iframe");
        if (!elems.length) return null; //No iframe found, FAILURE
        for (var i=0; i<elems.length; i++) {
           if (/^https?:\/\/(?:www\.)?youtube(?:-nocookie)?\.com(\/|$)/i.test(elems[i].src)) break;
        }
        elem = elems[i]; //The only, or the best iFrame
        if (elem.id) return elem.id; //Existing ID, return it
        // else: Create a new ID
        do { //Keep postfixing `-frame` until the ID is unique
            id += "-frame";
        } while (document.getElementById(id));
        elem.id = id;
        return id;
    }
    // If no element, return null.
    return null;
}

// Define YT_ready function.
var YT_ready = (function() {
    var onReady_funcs = [], api_isReady = false;
    /* @param func function     Function to execute on ready
     * @param func Boolean      If true, all qeued functions are executed
     * @param b_before Boolean  If true, the func will added to the first
                                 position in the queue*/
    return function(func, b_before) {
        if (func === true) {
            api_isReady = true;
            while (onReady_funcs.length) {
                // Removes the first func from the array, and execute func
                onReady_funcs.shift()();
            }
        } else if (typeof func == "function") {
            if (api_isReady) func();
            else onReady_funcs[b_before?"unshift":"push"](func); 
        }
    }
})();
// This function will be called when the API is fully loaded
function onYouTubePlayerAPIReady() {YT_ready(true)}

// Load YouTube Frame API
(function() { // Closure, to not leak to the scope
  var s = document.createElement("script");
  s.src = (location.protocol == 'https:' ? 'https' : 'http') + "://www.youtube.com/player_api";
  var before = document.getElementsByTagName("script")[0];
  before.parentNode.insertBefore(s, before);
})();

// Ранее были определены основные функции. Посмотрите вперед для реализации:

var player; //Define a player object, to enable later function calls, without
            // having to create a new class instance again.

// Add function to execute when the API is ready
YT_ready(function(){
    var frameID = getFrameID("tabs2");
    if (frameID) { //If the frame exists
        player = new YT.Player(frameID, {
            events: {
                "onStateChange": stopCycle
            }
        });
    }
});

// Example: function stopCycle, bound to onStateChange
function stopCycle(event) {
    alert("onStateChange has fired!\nNew state:" + event.data);
}

Если вы хотите вызвать дополнительные функции на более позднем этапе, например, отключить видео, используйте:

player.mute();
  • Если вам нужно только вызвать простые однонаправленные функции , использовать этот код не обязательно. Вместо этого используйте функцию callPlayer, как определено в этот ответ .
  • Если вы хотите реализовать эту функцию для нескольких кадров , одновременно взгляните на этот ответ . Также включает подробное объяснение getFrameID и YT_ready.
1 голос
/ 13 июня 2013

Со вчерашнего дня это больше не работает. OnStateChange не запускается. Джеффри опубликовал быстрое исправление, но я не могу обновить приведенный выше ответ

Больше информации об этом выпуске https://code.google.com/p/gdata-issues/issues/detail?id=4706

Все заработало :-) с исправлением

Добавить следующую функцию

function onReady() {
    player.addEventListener('onStateChange', function(e) {
        console.log('State is:', e.data);
    });
}

и перед "onStateChange": stopCycle добавить "onReady": onReady,

1 голос
/ 03 ноября 2011

Вы можете использовать плагин tubeplayer , он содержит множество событий для прослушивания.

0 голосов
/ 30 ноября 2015

У меня есть эта функция в моем чате, которая позволяет пользователям публиковать видео с YouTube.URL-адрес vid прикреплен как источник существующего iframe с идентификатором.

Что я заметил, так это то, что добавлено -although? Enablejsapi = 1 - сценарий работает только с далеко существующими iframe при загрузке страницы.

Как поступить, если этот скрипт должен связываться после установки нового источника для iframe?

...