Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

WordPress

Ben Anggoro
Ben Anggoro
36,161 Points

Using Youtube API on WordPress - another Chrome quirks

Hello again everyone,

Wondering if anyone have experience using Youtube API on a WP Theme development?

I'm using CSS tricks Play and Pause Buttons for YouTube and Vimeo Videos (via Their APIs) as reference.

To retrieve the youtube video on single page, I use the following:

....

$videoURL = get_post_meta( $post_id, '_format_video_embed', true );
if($videoURL) {
            if(strpos($videoURL, 'youtube') > 0 ) {
                $videoURL = explode('v=', $videoURL);
                $videoURL = explode('&',$videoURL[1]);
                $youtubeID = $videoURL[0]; 
                echo '<iframe src="//youtube.com/embed/' . $youtubeID . '?enablejsapi=1&controls=0&showinfo=0" frameborder="0" id="' . $youtubeID .'"></iframe><div id="play-button" class="icon icon-play"></div>
                        <div id="pause-button" class="pause icon-pause"></div>'; 

....
and so on

And since the tricks on CSS Tricks throws error... again on Chrome... I used this snippet by Rob W. that I found on stack overflow

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 / 0 = 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 (!domReady ||
               iframe && (!iframe.contentWindow || queue && !queue.ready) ||
               (!queue || !queue.ready) && 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);
    }
}

and then actually calling the player

callPlayer(bwnp.youtubeID, function(){
    var playButton = document.getElementById('play-button');
    var pauseButton = document.getElementById('pause-button');

    playButton.addEventListener("click", function() {
    callPlayer(bwnp.youtubeID, 'playVideo');
    });

    pauseButton.addEventListener('click', function() {
        callPlayer(bwnp.youtubeID, 'pauseVideo');
    });
});        

It works fine on Firefox but not on chrome. Im not too sure about safari but probably same. On chrome, it seems to be stuck when loading yimg something

Anyone having experience on this and would see where I messed up the thing? Or do I need to use wp codex way of embedding the thing? But if so then is it still possible working with youtube API? Because what I know if to use the API, the video URL should be as above and using WP oembed would give a different result, I suppose?

By the way, referencing from the same, I have no problem with vimeo on any browser. Just youtube and chrome.

Thanks in advance I really do sometime feel like I should just grow potatoes :D

Ben Anggoro
Ben Anggoro
36,161 Points

Nevermind i think it's my connection.

4 Answers

Ben Anggoro
Ben Anggoro
36,161 Points

OK after all, API won't play on iOS anyway so... back to just getting the video thumbnail and set it as featured image and then only shows the video on single thats the best for performance I think

Zac Gordon
STAFF
Zac Gordon
Treehouse Guest Teacher

Hey Ben, was this a connectivity issue?

Ben Anggoro
Ben Anggoro
36,161 Points

Oh wow mr Zac Gordon himself replying to me! :) Thanks Zac!

I'm not too sure. Sometimes it works, sometimes it makes chrome and safari stalled, but never happened on Firefox. The thing is the problem never occur if I use the codex embed way, like apply filter embed etc.

I keep having problems with chrome lately I dont know why. For example now suddenly anything about scrolling or smooth scrolling won't work on Safari or Chrome, while no problem on FF.

Is there any specific tricks to make this smooth scrolling business works on wordpress on chrome, Zac? For example a simple jquery snippet like this won't work on webkit but no problem on FF:

  $('.scroll-down').click(function(){
    $('html,body').animate({
        scrollTop: $(this).offset().top},
        'slow');
  });

It's kind of frustrating because I've been practically wasting hours for this very small but very irritating issue and seriously makes me wish I could just grow potatoes lol.

Would you help me out please Zac? What did I do wrong on the above so it won't work on Webkit?

I obviously wrapped it in WP's no-conflict brackets.

Thanks so much! Ben

Ben Anggoro
Ben Anggoro
36,161 Points

Hi again Zac

Im not too sure if my membership plan allows me to do this but here's the link to the project that I am currently working on, just in case you would like to have a look on the code.

Thanks! Ben

Link to the project