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.
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.
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!
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
Hmm. Looks like IE doesnt support Beacon. The company has IE installed as default on all employees computers, so its essential this platform works on IE.
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?
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.