1

First I want to say thanks to Kosmos for his amazing answer.

How to control youtube video play & pause depend on visibility of the frame or player. Is there any way to do this with youtube embed videos with HTML Tabs?

For example :

<br><br><br>

<div class="container">

    <ul class="tabs">
        <li class="tab-link current" data-tab="tab-1">Tab One</li>
        <li class="tab-link" data-tab="tab-2">Tab Two</li>
        <li class="tab-link" data-tab="tab-3">Tab Three</li>
        <li class="tab-link" data-tab="tab-4">Tab Four</li>
    </ul>

    <div id="tab-1" class="tab-content current">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    </div>
    <div id="tab-2" class="tab-content">
         Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </div>
    <div id="tab-3" class="tab-content">
        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
    </div>
    <div id="tab-4" class="tab-content">
<iframe id="playerA" width="300" height="220" src="https://www.youtube.com/embed/0_P4pKbvaII?rel=0" frameborder="0" allowfullscreen></iframe>
    </div>

</div><!-- container -->

If the above frame visible the video autoplay and if the frame hide or scroll down like DEMO jsfiddle it will auto pause.

JS Answer from Kosmos which is works great with scroll method (thanks to him) that mean if user scroll away the video pause and if again scroll to video frame in viewport it start playing. No My Question is how can implement this with HTML tabs

var LoadVideo = function(player_id){
    var Program = {
        Init: function(){
            this.NewPlayer();
            this.EventHandler();
        },

        NewPlayer: function(){
            var _this = this;
            this.Player = new YT.Player(player_id, {});
            _this.Player.$element = $('#' + player_id);
        },

        Play: function(){
            if( this.Player.getPlayerState() === 1 ) return;
            this.Player.playVideo();
        },

        Pause: function(){
            if( this.Player.getPlayerState() === 2 ) return;
            this.Player.pauseVideo();
        },

        ScrollControl: function(){
            if( Utils.IsElementInViewport(this.Player.$element[0]) ) this.Play();
            else this.Pause();
        },

        EventHandler: function(){
            var _this = this;
            $(window).on('scroll', function(){
                _this.ScrollControl();
            });
        }

    };

    var Utils = {

        /** @author https://stackoverflow.com/a/7557433/1684970 */
        IsElementInViewport: function(el){
            if (typeof jQuery === "function" && el instanceof jQuery) el = el[0];
            var rect = el.getBoundingClientRect();
            return (
                rect.top >= 0 &&
                rect.left >= 0 &&
                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
            );
        }

    };

    Program.Init();
};

window.onload = function(){
    LoadVideo('playerA');
    LoadVideo('playerB');
    LoadVideo('playerC');

    // or (loop mode)

    //$('iframe').each(function(){
    //  LoadVideo($(this).attr('id'));
    //});
};

Please help or share your idea will be highly appreciate. Thanks!

Community
  • 1
  • 1
Firefog
  • 2,532
  • 5
  • 31
  • 68

2 Answers2

8

Well, I made a simple example to do what you are looking for using the Youtube Iframe API.

Here's the jsfiddle: https://jsfiddle.net/kmsdev/gsfkL6xL/

And here's the code (see the API docs to understand it better):

Edit:

Example code updated to match OP requests. I just added an event handler to listen to tab click events. Don't forget to append &enablejsapi=1 to the iframe source url, else the API won't work. Since the idea now is a little more than just play and stop the videos by scroll, maybe this code is not the best option, but it is still a workaround.

Updated jsFiddle: https://jsfiddle.net/kmsdev/gsfkL6xL/3/

var LoadVideo = function(player_id){

    var Program = {

        Init: function(){
            this.NewPlayer();
            this.EventHandler();
        },

        NewPlayer: function(){
            var _this = this;
            this.Player = new YT.Player(player_id, {});
            _this.Player.$element = $('#' + player_id);
        },

        Play: function(){
            console.log(this.Player.IsReady);
            if( this.Player.getPlayerState() === 1 ) return;
            this.Player.playVideo();
        },

        Pause: function(){
            if( this.Player.getPlayerState() === 2 ) return;
            this.Player.pauseVideo();
        },

        ScrollControl: function(){
            if( Utils.IsElementInViewport(this.Player.$element[0]) ) this.Play();
            else this.Pause();
        },

        EventHandler: function(){
            var _this = this;
            $(window).on('scroll', function(){
                _this.ScrollControl();
            });

            $('.tab-link').on('click', function(){
                var $target = $('#' + $(this).data().tab);
                if( !!$('iframe', $target).length && $('iframe', $target).attr('id') == _this.Player.$element.attr('id') ){
                    _this.Play();
                }
            });

        }

    };

    var Utils = {

        /** @author http://stackoverflow.com/a/7557433/1684970 */
        IsElementInViewport: function(el){
            if (typeof jQuery === "function" && el instanceof jQuery) el = el[0];
            var rect = el.getBoundingClientRect();
            return (
                rect.top >= 0 &&
                rect.left >= 0 &&
                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
            );
        }

    };

    Program.Init();

};

window.onload = function(){
    LoadVideo('playerA');
    LoadVideo('playerB');
};

Feel free to use and modify it for your purpose.

kosmos
  • 4,202
  • 1
  • 16
  • 34
  • If you need explanation for the code just tell me, I can do it later. – kosmos Dec 21 '15 at 10:50
  • your answer works great during scroll but I am a bit confuse about tab. For example if there is 3 tab does it play when the video tabs open Example: Description>>Video>>download these are three tab and when ppl click on video tab the video should start playing. and when click on other tab it pause. some thing like viewpost but I am not sure. One again thanks for you. – Firefog Dec 21 '15 at 11:01
  • You are talking about html tabs, right? In the `ScrollControl()` method, just change the `if` to something like `if( Utils.IsElementInViewport(this.Player.$element[0]) && this.Player.$element.parent().is(':visible') )`. Remember that you have the iframe jQuery element in `this.Player.$element`, so you can work with it easily. – kosmos Dec 21 '15 at 11:31
  • could you please check [JSFIDDLE](https://jsfiddle.net/2p2hr1aj/) why this not working as you mentioned in your above comment – Firefog Dec 21 '15 at 15:16
  • It was just an example since I didn't know how was your html structure. Seeing the HTML in the jsfiddle clarifies the things. It won't work because there is no scroll event if there are no scrolling bars. Also, what you are looking for is to work with html tabs, what changes the things. Next time please post all relevant code (in this case js and html). For now update your question with your current code and don't forget to append the html part too, so more people can help. The scroll logic will work, now you only need to control where to play and stop videos through "tab-click" events. – kosmos Dec 21 '15 at 19:26
  • Thanks for your advice. Question has been updated with your solution :) Thanks – Firefog Dec 21 '15 at 19:53
  • I have modified the code in the answer to make it work again. – kosmos Dec 22 '15 at 07:19
  • in my case I had to wrap `LoadVideo()` into `window.onYouTubeIframeAPIReady` – Patrioticcow Feb 17 '17 at 18:13
0

I'm aware this is an old question but I found a solution that fits my need perfectly so I thought I would share it. I found out you can actually append &autoplay=1 to the iframe src, it automatically plays the video. No need for the Youtube IFrame API

$(window).scroll(function() {
 
//will trigger when your element comes into viewport
    var hT = $('#YourElement').offset().top,
    hH = $('#YourElement').outerHeight(),
    wH = $(window).height(),
    wS = $(this).scrollTop();

if (wS > (hT+hH-wH)){
        //appends &autoplay=1 to iFrame src, making it autoplay
        var videoUrl = $('#YourIFrame').attr('src');
        $('#YourIFrame').attr('src', videoUrl + "&autoplay=1");
    }
moz
  • 21
  • 2