Slick Carousel : Pause the Slick autoplay when youtube video is playing
Asked Answered
P

2

7

I am using http://kenwheeler.github.io/slick/ for the carousal. But the problem is the autoplay slides the slick to next even when the youtube video is playing.

JSFIDDLE

Currently I am using the below JS but nothing seems to work on it.

$('#main-slider').slick({
      slidesToShow: 1,
      slidesToScroll: 1,
      autoplay: true,
      autoplaySpeed: 3000,
      dots: true,
      infinite: true,
      adaptiveHeight: true,
      arrows: false
  });

  var video = $('#main-slider .slick-active').find('iframe').get(0).play();

  $('#main-slider').on('afterChange', function(event, slick, currentSlide, nextSlide){
    $('#main-slider .slick-slide').find('video').get(0).pause();
    var video = $('#main-slider .slick-active').find('video').get(0).play();
});

There are few similar question but none of them has a solution. Slick-carousel how to stop autoplay when video is on via youtube api

Pix answered 15/11, 2017 at 7:13 Comment(1)
You have to apply YouTube API to take control of the states of your videos, then the slider autoplay will be toggled from that.Sulfonation
P
1

Please find the solution here:

Fiddle : http://jsfiddle.net/rijokpaul/pyzpg7st/2/

I solved it with YouTube Iframe API

    var tag = document.createElement('script');
    tag.id = 'iframe-demo';
    tag.src = 'https://www.youtube.com/iframe_api';
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    var player;
    function onYouTubeIframeAPIReady() {
        var elems1 = document.getElementsByClassName('yt-player');
        for(var i = 0; i < elems1.length; i++) {

            player = new YT.Player(elems1[i], {
                events: {
                    //'onReady': onPlayerReady,
                    'onStateChange': onPlayerStateChange
                }
            });
        }
    }
    function onPlayerReady(event) {

    }
    function handleVideo(playerStatus) {
        if (playerStatus == -1) {
            // unstarted
            $('#main-slider').slick('slickPause');
        } else if (playerStatus == 0) {
            // ended
            $('#main-slider').slick('slickPlay');

        } else if (playerStatus == 1) {
            // playing = green                
            $('#main-slider').slick('slickPause');                
        } else if (playerStatus == 2) {
            // paused = red
            $('#main-slider').slick('slickPlay');
        } else if (playerStatus == 3) {
            // buffering = purple
        } else if (playerStatus == 5) {
            // video cued
        }
    }
    function onPlayerStateChange(event) {
        handleVideo(event.data);
    }

    $(function() {
        $('#main-slider').slick({
            slidesToShow: 1,
            slidesToScroll: 1,
            autoplay: true,
            autoplaySpeed: 3000,
            pauseOnFocus: false,
            pauseOnHover: false,
            dots: true,
            infinite: true,
            adaptiveHeight: true,
            arrows: false
        });

    });

    $('#main-slider').on('beforeChange', function(event, slick, currentSlide, nextSlide){
        $('.yt-player').each(function(){
            this.contentWindow.postMessage('{"event":"command","func":"' + 'pauseVideo' + '","args":""}', '*')
        });
    });

Also updated iframe like the following

<iframe class="yt-player" src="https://www.youtube.com/embed/lqj-QNYsZFk?controls=1&rel=0&enablejsapi=1"></iframe>

Added &enablejsapi=1 at the end of iframe url and used a class called yt-player.

UPDATE

Commented onReady function and used slick beforeChange event to pause YouTube video when it is not active.

Patricide answered 14/3, 2018 at 9:47 Comment(3)
its working fine but the only issue is while a video is playing and we go to next slide the video continues to play in background.Pix
the first time after loading if you click on the video it slides away and when the playback starts it pauses the slideshow resulting in displaying the wrong video thumb when the video is already playing in the backgroundKarren
I have updated my answer as per the requests. Updated background video issue and corrected wrong thumbnail on slider change as well.Patricide
E
0

using slick and videojs together is hard, too many bug (event/condition that we need to handle manually) in there especially using youtube as source.

i explain how to do this inside the code: fiddle

$(function(){
    var videoPlayed = false;

    function pauseSlider(){
        myslider.slick('slickPause');
    } 

    function playSlider(){
        myslider.slick('slickPlay');
    }

    /*
        assign videojs handle on pause and play dinamically.
        place this script before slick initialize only.
        because slick will cloned our element, so we will confuse to assign event handle on our videjs element

        but if you want it you change selector from `.video-slider` to `"#main-slider .slick-slide:not(.slick-cloned) .video-slider"`
    */
    //$("#main-slider .slick-slide:not(.slick-cloned) .video-slider").each(function(i,e){
    $(".video-slider").each(function(i,e){
        var id=$(this).attr('id');
        videojs.players[id].on("pause", function(){
            videoPlayed= false;
            playSlider();
        });
        videojs.players[id].on("play", function(){
            pauseSlider();
            videoPlayed= true;
        });
    });

    var myslider = $('#main-slider').slick({
        slidesToShow: 1,
        slidesToScroll: 1,
        /*
            when video play, slider is stopped. 
            but when event mouseout (hover out)/focus out triggered, 
            the slider will contine to play again.
            this is because pauseOnHover and pauseOnFocus default true.
            And because you want adaptiveHeight (full screen slider), 
            i assume you no need to doing pauseOnHover, because all time mouse will stay inside your slider.
            in this case we need to change pauseOnHover and pauseOnFocus to false
        */
        pauseOnHover:false,
        pauseOnFocus:false,
        autoplay: true,
        autoplaySpeed: 3000,
        dots: true,
        infinite: true,
        adaptiveHeight: true,
        arrows: false
    });

    $('.video-slider').click(function(){
        if(videoPlayed){
            /*
                actually this is will never executed. but sometimes 
                this will execute if user spam play pause on slow network.
                so we still leave here to handle if videojs pause event not called.
            */
            videojs($(this).attr('id')).pause();//pause video 1st then play the slider
            videoPlayed= false;
            playSlider();
        }else{
            pauseSlider();//pause slider 1st then play the video
            videojs($(this).attr('id')).play();
            videoPlayed= true;
        }
    });
});
Extensive answered 12/3, 2018 at 10:38 Comment(2)
its not working. Its going to next slick even when the video is playingPix
yes. i found it after try several debugging attempt: my script is actually works, but there is a bug: when slider start transition and then we click/play the video, video will play but slider still finish transition after that slider will paused. ex: video1 played, but slider stop at video2 thumbnail. try to reproduce this issue using speed: 10000 then try click when transition happen. To fix this bug is really depends on the situation, the easy way is to set speed: 200 =>fast , so we not giving user chance to click while transition happened. but i still figure out to do this correctlyExtensive

© 2022 - 2024 — McMap. All rights reserved.