1

I have the following interval which updates the progress value while a YouTube video is playing. It works fine most of the cases but in some other cases the progress does weird things like going back and forth and I get the following error in the console.

NotSupportedError: DOM Exception 9: The implementation did not support the requested type of object or operation.

This occurs in all browsers and it mostly happens when I load a new video.

if(player) {
    player.loadVideoById({'videoId': data.yt_id});
}

Does anyone know why is this happening and how can I fix this?

var value = 0;
var duration = player.getDuration();
var progress = document.getElementById('progress');

var to = setInterval(function() {
    value = 1 / duration * player.getCurrentTime();
    progress.value = value;
}, 250);

The error fires on: progress.value = value;

progress is a <progress> element.

console.log():

value: 0.02622895199857715
youtube.js:104 player.getCurrentTime(): 5.417367
youtube.js:103 value: 0.02746555095910624
youtube.js:104 player.getCurrentTime(): 5.672776
youtube.js:103 value: 0.02870214991963533
youtube.js:104 player.getCurrentTime(): 5.928185
youtube.js:103 value: 0.029826330792843594
youtube.js:104 player.getCurrentTime(): 6.160375
M1X
  • 4,971
  • 10
  • 61
  • 123
  • 1
    What line is the error triggering on? – Patrick Evans Jan 19 '16 at 21:47
  • The error fires on: `progress.value = value;` @PatrickEvans – M1X Jan 19 '16 at 21:47
  • 1
    What is progress? `` element? – Patrick Evans Jan 19 '16 at 21:49
  • Yes It is a `` element. – M1X Jan 19 '16 at 21:51
  • 1
    Can you console.log out "1 / duration * player.getCurrentTime()" so we can see what that value is? Wondering if progress needs an int between 0 and progress.Maximum – bri Jan 19 '16 at 22:04
  • It doesen't print nothing in Safari. It prints `0.3744603598331141` and so on in Chrome and Firefox and in Firefox it gives this error: `TypeError: Value being assigned to HTMLProgressElement.value is not a finite floating-point value.` @bri – M1X Jan 19 '16 at 22:13
  • OK. One last question: for any given moment (or 2 or 3), can you log out and tell us what duration is (eg - the value) and what getCurrentTime() is yielding (eg - the value). – bri Jan 19 '16 at 22:25
  • See the updated question. @bri – M1X Jan 19 '16 at 22:43

1 Answers1

1

I'd add this as a comment, but it might get a little long. May help you to go back to basics on this one and use some Integer values for progress object.

Progress Basics

I've always used progress object like this:

<progress id="myProgressBar" value="1" max="100"></progress>

Then, set progress.value as an integer between 0 and 100 (or whatever MAX is) ...

document.getElementById("myProgressBar").value = 10;
// code ...
document.getElementById("myProgressBar").value = 20;
 // code...
document.getElementById("myProgressBar").value = 30;
// etc ...

YouTube API

According to this super helpful post:

player.getCurrentTime():Number

Returns the elapsed time in seconds since the video started playing.

player.getDuration():Number

Returns the duration in seconds of the currently playing video. Note that getDuration() will return 0 until the video's metadata is loaded, which normally happens just after the video starts playing.

Your Code

So, now we know (because stackoverflow SAID so) that duration is in seconds and we know (ibid) that player.getCurrentTime() is also yielding seconds. Given those facts, we can just do the following:

var duration = player.getDuration();
var progress = document.getElementById('progress');
if(duration!=undefined) { progress.max = parseInt(duration); }

var to = setInterval(function() {
    //just in case we got "0" last time.
    if(duration==undefined || duration == 0) {
       duration = player.getDuration(); 
       if(duration==undefined || duration==0) { return; }
       progress.max = duration;
    }
    var currentProgress = parseInt(player.getCurrentTime());
    if(currentProgress <= duration) { progress.value = currentProgress; }
}, 1000);

Of course, this is TOTALLY UNTESTED code... Like I said - it should really be a comment, but comments are so ... limited ;-). I'd put loggers in that interval code to see what values I'm getting for duration and for "currentProgress" as a next step... Then, once it's working, I'd wrap it in a try to avoid hiccups from the youTube api. But, that's just me.

Oh. And we are counting seconds, not 1/4 seconds...

Oops... one last thing. Since we are tracking seconds, I changed the interval to fire every second. No reason to fire 4 times if my update interval isn't going to change.

If you wanted to track 1/10 of a second, I guess you could multiple both duration and getCurrentTime by 10 before you parseInt() them.

Hope it at least points you in the right direction.

Community
  • 1
  • 1
bri
  • 2,932
  • 16
  • 17
  • 1
    Yeah. That's probably my copy/paste idiocy. can you ditch the :Number silliness (per the updated code) in the 3 places I copied it? Try one more time. – bri Jan 19 '16 at 22:57
  • Yeah but I still need to see this solution one by line to understand it better. @bri – M1X Jan 19 '16 at 23:06
  • Why the progress updates so slow even if I set to 50ms. @bri – M1X Jan 19 '16 at 23:11
  • Because you are using seconds as your progress meter (see that last part about multiplying duration and interval by 10 ... – bri Jan 19 '16 at 23:59