Youtube iFrame API: fire an event every 5 minutes

Hi all

Im currently working with the youtube iframe API with jquery.

Its important that the user can pick up where they last left off. At the moment, I have a button which they can click to save the progress; and also whenever they pause a video it saves the progress. But - as a fool proofs solution - I want to cater for whether they click the browser back button; or close the browser.

My videos are 60 minutes in length - so if they get to 55 minutes, and then close the browser, I dont want the user to have to watch the video for 55 minutes again.

I hope that makes sense.
Thanks

Well let’s break the problem down. We first need to detect when a user closes a tab or their browser so we can execute some code when that happens. To help with this, you might want to check out the onbeforeunload event.

When they close the window, we need to get the player and determine where in the video they are at so we can record the time to return to. Looking at the YouTube Player API reference we can see a function called player.getCurrentTime() which will get the elapsed time since the player started playing. You will also see on this page (link below) that you can use a player.seekTo() to then set the place in the video to start playing again from.

So in short, when they close the browser, it triggers your closing event, you read the player at where it is in the video and save that time (in seconds) somewhere (maybe localStorage) and then when the page loads again, have some code to fetch that value and seek to that place in the video to start playing again.

Take a quick look at the links I provided above and maybe that will help you out. :slight_smile:

It could also be done without needing to worry about the back button or closing the browser.

You could just have setInterval run every second where it updates to local storage the video being watched and their current time.

That way regardless of how things left off, the information is retained about were they last were.

Wow - thanks so much guys. This is useful.
Im going try try saving the currentTime value to a database becuase I cant be sure the user will e on the same computer when they next log back into the website.
Thanks!

In the case of a database, you may want to hit that less often than every second, such as every 10 seconds or so.

Thanks @Paul_Wilkins
At the moment I have the currentTme stored via a ‘Save progress’ button (that the user has to manually click on). I then discovered the onPause event, so Im using that to store the currentTime. So I think the onbeforeunload event handler is the last piece in the puzzle. Failing that, I will - as you say - store the currentTime every 10 seconds or so.

Hmm. Im trying to use the beforeunload event handler. I cant get it to fire anything when the user clicks back/forward. Only when the user refreshes the page do I get a dialogue box. What am I doing wrng?

My code:

	<script src="//code.jquery.com/jquery-1.11.1.min.js"></script> 
	<script>

	window.addEventListener('beforeunload', function (e) {
	alert("this doesnt display!")
  // Cancel the event
  e.preventDefault(); // If you prevent default behavior in Mozilla Firefox prompt will always be shown
  // Chrome requires returnValue to be set
  e.returnValue = '';
});


		</script>

ARGH! Im obviously missing something really simple here, but every tutorial I go to simply doesnt work. Ive tried in Chrome/Firefox/Brave. I just cant get the beforeunload event to fire.

I am right in thinking this should fire if the user reloads/clicks a link which will take them to another page/clicks the back/forward browser buttons?

Can someone point out the obvious mistake Im making?
Thanks

Hi @bolton, aleret()ing inside a beforeunload will not work indeed (that’s where you’d use the returnValue instead)… try logging something to the console with “preserve log” enabled in the dev tools.

Another idea would be to send a beacon instead so you don’t have to worry about unload events etc.; this would probably be more reliable anyway. For example:

const script = document.createElement('script')

script.src = 'https://www.youtube.com/iframe_api'
document.head.appendChild(script)

function submitProgress (player) {
  const data = new URLSearchParams()

  data.append('id', player.getVideoData().video_id)
  data.append('progress', player.getCurrentTime())
  navigator.sendBeacon('save-progress', data)
}

window.onYouTubeIframeAPIReady = function () {
  const player = new YT.Player('my-player')
  let handle = null

  player.addEventListener('onStateChange', event => {
    if (event.data === YT.PlayerState.PLAYING) {
      handle = window.setInterval(submitProgress, 5000, event.target)
    } else {
      window.clearInterval(handle)
    }
  })
}

PS: I’d strongly suggest to use a more recent version of jQuery, you’re 2 major versions behind. oO

I’m pretty sure that onbeforeunload doesn’t do anything these days in some browsers for security reasons, and only shows a generic message now.

Hmm. Looks like IE doesnt support Beacon. :frowning: The company has IE installed as default on all employees computers, so its essential this platform works on IE. :frowning:

I can log a message to the console, but cant get it to do anything else! My code:

$(window).unload(function() {
           console.log('starting to hate my life');
			var request = $.ajax({
			  url: "process-save-progress.php",
			  method: "POST",
			  data: { videoID : 'zKwzswgUjHo', video_duration: '20', current_time: '10'}
			});
});	

I am right in thinking that the ajax should fire am I?

Thanks (as ever! :slight_smile: )

Hmmm, interestingly, If I put my ajax script into a function; and then call that function within the unload event - it works!! Odd.
Thanks so much all - I always learn a lot from you guys.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.