Go To Next Slide When Vimeo Finished

If you are using Squarespace Gallery block to host Vimeo videos, it makes sense go to next slide when video stops playing. And this actually can be easily done.

So we need to know when exactly the Vimeo video ends.

1) We may use their Player.js  for that. Good call, but only if we need some more extra using Vimeo API. Also in this case we need to pass iframe element to Player class and this will be a little bit tricky, because Squarespace Videoloader dynamically adds video iframe in the moment you click Play button by default.  

2) Almost all communication with iframes using window.postMessage() method. And Vimeo iframe already posts ready event messages to our top window. After ready event we may tell the iframe to push other messages to main window and control the video also.

I found second way more simple and clean. So here is the logic: 

  1. Wait for window.onload ($(document).ready or Y.on('domready')) event to make sure Gallery was initialized.

  2. Subscribe to message event.

  3. Check for ready message and make sure it has Vimeo URL origin and iframe content window is equal current active slide iframe.contentWindow (to be sure it is not a message from some other iframe on the page)

  4. Use addEventListener method to make iframe post proper messages to our window

  5. If this is an event we are waiting for - call the Next Slide.

  6. After the slide changed, check the new slide for video, and play it.

Two words about 5 clause: I saw many codes from devs, who trigger next/prev slide from code with simulating 'click'  on gallery controls (arrows). Well, it makes sense, even if Squarespace will change something in their gallery code. But while I may retrieve galleries instance (with the ability to call all other Gallery methods) from GalleryManager or from Gallery Node with the code below, let me use that. 

<script>
    //array with galleries instances on page
    var all_galleries = Y.Squarespace.GalleryManager.getGalleries()
    //gallery instance from first gallery node on page.
    //you may use #gallery-block-id selector to choose the gallery you need
    var gallery = Y.one('.sqs-block-gallery .sqs-gallery').getData('gallery')
</script>

So I need to use this for first gallery on page and here is the full code you may inject to Header/Footer or Page Injection Tab:

<script>
function isVimeoUrl(url) {
    return ( /^(https?:)?\/\/(player.)?vimeo.com(?=$|\/)/.test(url)) ;
}
Y.on('domready', function() {
    var firstGallery = Y.one('.sqs-block-gallery .sqs-gallery');
    var gallery = firstGallery.getData('gallery');
    var autoplay_next_video = false;
    if (gallery) {
        gallery.after('currentIndexChange', function() {
            setTimeout(function() {
                if (firstGallery.one('.sqs-active-slide .sqs-video-wrapper') && autoplay_next_video) {
                    var videoloader = firstGallery.one('.sqs-active-slide .sqs-video-wrapper').videoloader;
                    videoloader.showVideo() && videoloader.play();
                    autoplay_next_video = false;
                }
            }, 500)
        })
    }
    window.addEventListener("message", function(e) {
        if (!isVimeoUrl(e.origin)) {
            return;
        }
        var data = e.data;
        if (JSON.parse(data) && firstGallery) {
            data = JSON.parse(data);
            var activeSlide = firstGallery.one('.sqs-active-slide');
            var video = activeSlide.one('.sqs-video-wrapper iframe');
            if (video) {
                if (video.getDOMNode().contentWindow !== e.source) {
                    return;
                }
                if (data.event == 'ready') {
               video.getDOMNode().contentWindow.postMessage('{"method": "addEventListener", "value": "ended"}', "*");
                    autoplay_next_video = false;
                } else if (video && data.event == 'finish') {
                    autoplay_next_video = true;
                    firstGallery.getData('gallery').nextSlide();
                }
            }
        }
    }, !1)
});
</script>
Previous
Previous

Parallaxing Map in Brine-family templates

Next
Next

Squarespace Websites Uploader