11

Hi I am using youtube iframe embed API. I want to track seek video event by user. Please help me how can I track this.

NorthCat
  • 9,643
  • 16
  • 47
  • 50
patilvikasj
  • 137
  • 2
  • 9
  • 2
    I have investigated for youtube api events but there is no seek event availabe in APIs . I need to run my callback function when user seek video . – patilvikasj Mar 27 '15 at 05:37
  • according to the [documentation](https://developers.google.com/youtube/js_api_reference#Events) there is no way to track such event, the only way to do this is to track yourself the `player.getCurrentTime()` at interval and checking if the video time is is coherent with the interval – dvhh Mar 27 '15 at 07:25

2 Answers2

16

There is no simple way to track the event with the api alone.

What you could to is running a javascript function in interval and check if the time difference measured is different from the one expecting

Here is an example code :

<html>
    <body>
        <div id="player"></div>
        <script>
            var tag = document.createElement('script');
            tag.src = "https://www.youtube.com/iframe_api";

            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

            var player;

            function onYouTubeIframeAPIReady() {
                console.log("ready");
                player = new YT.Player('player', {
                    height: '390',
                    width: '640',
                    videoId: 'cRmNPE0HwE8',
                    events: {
                        'onReady': onPlayerReady,
                            'onStateChange': onPlayerStateChange
                    }
                });
                //console.log(player);
            }

            function onPlayerReady(event) {
                event.target.playVideo();

                /// Time tracking starting here

                var lastTime = -1;
                var interval = 1000;

                var checkPlayerTime = function () {
                    if (lastTime != -1) {
                        if(player.getPlayerState() == YT.PlayerState.PLAYING ) {
                            var t = player.getCurrentTime();

                            //console.log(Math.abs(t - lastTime -1));

                            ///expecting 1 second interval , with 500 ms margin
                            if (Math.abs(t - lastTime - 1) > 0.5) {
                                // there was a seek occuring
                                console.log("seek"); /// fire your event here !
                            }
                        }
                    }
                    lastTime = player.getCurrentTime();
                    setTimeout(checkPlayerTime, interval); /// repeat function call in 1 second
                }
                setTimeout(checkPlayerTime, interval); /// initial call delayed 
            }
            function onPlayerStateChange(event) {

            }
        </script>
    </body>
</html>
dvhh
  • 4,724
  • 27
  • 33
  • 1
    I would use window.requestAnimationFrame for better results. – Kirill Reznikov Feb 28 '19 at 03:36
  • @KirillReznikov I would avoid adding extra computation that is not about redrawing data in the window.requestAnimationFrame callback as it would detract from the user experience, you do not need to detect seek at the frame level – dvhh Mar 01 '19 at 03:37
-1

You can do it a little bit simply (without timers):

<script>
   const tag = document.createElement('script');
   tag.src = "https://www.youtube.com/iframe_api";
   const firstScriptTag = document.getElementsByTagName('script')[0];
   firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

   let previousAction;
   let previousTime;

   function onYouTubeIframeAPIReady() {
      player = new YT.Player('player', {
        events: {
          'onStateChange': onPlayerStateChange
        }
      });
   }

   function onPlayerStateChange({target, data}) {
     if(data != 3) { // we don't need to detect buffering
       return;
     }

     const currentTime = target.getCurrentTime();
     // detect existing action and previous action which is not paused
     if (!previousAction || previousAction != 2 ) {
        // return existing youtube api data (-1 || 0 || 1 || 5 )
        return data;
     } else if (Math.abs(previousTime - currentTime) > 1 ) {
        // we have Seek event and we have time when it was started(previousTime). Also we have finish time of Seek event(currentTime).
        return 'Seek'
     }

     previousTime = currentTime;
     previousAction = data
   }
</script>
Harret
  • 11