paulirish / lite-youtube-embed

A faster youtube embed.
https://paulirish.github.io/lite-youtube-embed/
Other
5.68k stars 260 forks source link

Interacting with the resulting player through the JS API #82

Closed nickeday closed 4 months ago

nickeday commented 3 years ago

Hey there, I can see in the "Custom Player Parameter's" section there's example usage of the enablejsapi parameter, though from what I can see at YouTube's documentation at https://developers.google.com/youtube/iframe_api_reference the only way to interact with an existing player is by having an id attribute set on the iframe and using that ID to create a YT.Player instance. It doesn't look like there's a way to set the ID on the iframe at the minute, or is there another method I should be using to interact with the player? Feels like I must be missing something at the moment! Very happy to create a PR to add the ID if that's what's needed.

arnaudlimbourg commented 2 years ago

If that is of interesting here is the way we solved it, using the component as a base and adding code to load the JS API

        this.addEventListener('click', e => {
            this.addIframe()
            this.loadJSAPI();
        });

        window.onYouTubeIframeAPIReady = () => {
            this.player = new YT.Player(`video-iframe-${this.videoId}`, {
                events: {
                    'onReady': () => {
                        if (this.actions.length > 0) {
                            this.actions.forEach(action => action());
                            this.actions = [];
                        }
                    },
                }

            });
        }
    }

    loadJSAPI() {
        if (YT == null) {
            const tag = document.createElement('script');
            tag.id = 'iframe-demo';
            tag.src = 'https://www.youtube.com/iframe_api';
            const firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        }
    }
Stolzenhain commented 2 years ago

the only way to interact with an existing player is by having an id attribute set on the iframe

you can also reference the DOM element like so
 

player = new YT.Player( document.querySelector('lite-youtube iframe'));

From my tests it looks like binding the click event works for initializing the API together with the component event like:

  var player;
 // control player via
 // https://developers.google.com/youtube/iframe_api_reference
 function onYouTubeIframeAPIReady() {

  document.querySelector('lite-youtube').addEventListener('click',function(){

   player = new YT.Player( document.querySelector('lite-youtube iframe'));

   //subscribe to events
   player.addEventListener("onReady", function(){
    console.log('ready');

    // dummy action works
    player.seekTo(60);

    player.addEventListener("onStateChange", function(){
     console.log('state change');
    });

   });

  });

 }

this looks a little dangerous to me, as the referenced iframe gets initialized at the same time … maybe a mutation observer or a slight timeout might make this safer. [Edit:] Also sorry for nesting callbacks …

paulirish commented 4 months ago

Now possible and easy via #164.