Weird bug on Videojs - javascript

I don't know how this happens and I can't see any errors.
I can't seem to navigate through the video the second time I open my page.
See screenshot here:
I have found this error it says,
TypeError: Floating-point value is not finite.
"Video is not ready. (Video.js)"
Help would be really appreciated.
Thanks

When you say "I can't seem to navigate through the video the second time I open my page"? Do you mean you aren't able to play the video at all or that you aren't able to fast-forward and rewind within the playing video?
That you are getting a Type Error: Floating-point value is not finite error means that a certain parameter you're supplying to video.js is of the wrong type. I.e. you probaby supply video.js with a string when it wants an integer (or something similar).
Because it works the first time you load the page, are you trying to resume playback where you left off when you navigated away from the page?
If that's the case you are probably storing the currentTime parameter in a cookie or localStorage value as a string (using jQuery cookies for example these usually get automaticalyl stringified) and forgetting to switch it back to an int when you need video.js to read it back to you. Because what I notice about your screenshot is it seems video.js doesn't know the duration of your video (i.e. the seek time says 0:31 / 0:00)
Here's what you should do:
Clear you cache to get a working first time player load then:
Before starting play back, after playback has finished, and during playback you should log the current playback time signature, i.e.: console.log( videojs("id-of-your-video").currentTime() )
Adding time signature console.logs() to these video.js event callbacks should help you:
durationchange (fired if the total duration of your video changes)
duration (tells you the duration of your video. Try logging this while it works and again after it stops working and see what's changed in the value)
If you're still having trouble try logging values using the video js timeupdate callback. This event is called when the current playback position has changed (can be several times a second). If all else fails this callback might give you some insight into the exact moment you're getting the invalid type value, but it won't help you if you're problems are with trying to resume playback from a .currentTime() value reading from an incorrect type stored in user cookie / sessionStorage / localStorage etc.

Are you Using a Server to execute it or are you running it locally. Because I got some similar issues when I ran it locally. But When I put the files in some server like tomcat or iis or whatever servers it worked. Not sure about the issue just a guess

Related

How to update a web page javascript counter live when the browser doesn't have focus?

I am making a browser game in html, css, and javascript, written in perl. Health and stamina are kept in the server and I use javascript to show the user a live updated count of these stats while the current page is loaded. This works fine, however if the user switches tabs or switches away from the browser and leaves it running in the background, the count value you see when you return does not keep up properly. So when you switch back to the browser, your counter might say 50/100 stamina when you actually have 100/100. So when you do something in the game (loads a new page) the server updates the counter to the true amount because the javascript is just keeping time to show the user a "live" rolling view in the browser.
Is there a way to ensure the javascript counter will continue to function even if the page/tab isn't active or on the forefront? Aside from completely re-writing my game to include continuous live server pushes in what is displayed on the browser to the user?
Say you are playing the game. You see your health and stamina regenerating. You switch to another program for a minute, then return to the game in the browser. You notice your health and stamina have not updated while you were away. But when you perform an action in the game, this value is updated to what it should be because it is tracked internally on the server. This is what I would like to fix. Hope that makes sense!
I have not tried anything to fix this issue yet besides searching the web and ending up on this site without a really "good" answer in sight, so I decided to ask the question.
Continuous server pushes wouldn't work either. Anything in the main event loop like a timer, or events happening when it's out of focus, gets slowed down by the browser to conserve resources. Some mobile browsers will stop it together.
The answer to the question is to change how your app keeps track of these stats.
Now some will say to use WebWorkers to run the timer in a separate thread but this won't solve all your issues. You'd still have a different version of the issue, like if someone restored your webpage from sleep or something along those lines. No background task can survive that.
You mention that you track these stats also on the server. That's convenient, so the most obvious thing you should do is detect when the tab comes back into focus using the Window focus event. You would then make all the calls to the server to fetch the most up-to-date stats and reset the timers based on that fresh data. To stop it from showing stale data while the request is in flight, you might choose to show a loading spinner or something during that period.
Another common way of fixing this is you keep around on each timer increment a var which says when the data last came back (a timestamp). When you leave focus, you detect this with the blur event and store that last timestamp somewhere. Then they come back into focus, you handle the focus event and calculate the difference between the current time and the last recorded time before defocus (blur). You may be able to recalculate from this period what the values should be.
But if your server has this info, it'd be far less error-prone and easy to just ask the server when they refocus.

Javascript - hide div 1 sec before live stream on video ends

I have this in page:
<video src="blob://some-live-stream" autoplay></video>
<div id="hideMePlease"> hide 1 sec before video ends</div>
I would like to hide the div 1 sec before the video ends, how can i do?
N.B: i can't know video duration, it's a live stream , and the video autostops so i have no way to stop it myself.
If, as you state, you cannot know the length of the video because it's streaming, it will be impossible (relativistic time travel notwithstanding) for you to schedule an event one second before it finishes.
However, I would at least first try to use the duration property of the video, it may be that metadata is made available as part of the stream early on. If it is, you can use that to schedule the hiding of your div.
As an aside, if you visit the page http://www.w3.org/2010/05/video/mediaevents.html, you'll find that the duration is set correctly as soon as you start playing the video, despite the fact it seems to be streaming from either an MP4, OGG or WEBM file). So it's at least possible, though it may depend on the data stream itself (whether the metadata comes before or after the actual video data).
If the data is not available (I think you get Inf for the duration in that case), then you're just going to have to hide the div at the earliest possible time after that.
That would presumably be when it finishes (fires the onended event).
So, in short, if you can get the duration (or periodically get the time remaining which might be better), use that. Otherwise fall back to hiding it at the end and start hassling w3c to provide the functionality you want in HTML6.

Track when the user received first bytes of the video

There is a web page which has HTML5 video in it. When the user clicked start or when he navigates through the timeline, the video starts (either from start or from the position he selected). But it does not always happens instantly. I wanted to find how much time did it took from the user click event and the time the user received first bytes of the video.
Getting time of userclick is not a problem, but while looking through HTML5 video API here and I was not able to find any event which is close to what I am looking for.
Is it possible to tack such event?
The event(s) you listen for after you receive the click (or "play" or "seeking") event depends on the state of the video before the time of the click.
If you have a fresh, unplayed video element with the preload attribute set to "none", then the first data you're going to receive from the network is the metadata. so you can listen for the "loadedmetadata" event.
If preload is set to "metadata", you might have already loaded metadata, depending on the browser and platform. (e.g., Safari on iPad will not load metadata or anything else until the first user interaction.) In that case, you want to listen for either "loadedmetadata" or "progress". It couldn't hurt to listen for "loadeddata" as well, but I think "progress" fires first.
If preload is set to "auto" or if you've already played some of the video, you might have some actual video data. And while you're likely to have data at the current point on the timeline, you may or may not have it at the seek destination. It depends at least on how far ahead (or behind) you're seeking, how fast data is coming in and how much spare room the browser has in the media cache.
If there is no data at the destination time (you can check this in advance if you want with the .buffered property, see TimeRanges), then the next event you see will be either "loadeddata" or "progress", probably followed by "canplay". If there is enough data buffered at the target time of the seek, then the question doesn't really apply because nothing else will be transferred.
However, in any of the above cases, once there is enough data to display the frame at the new point on that timeline and that data has been decoded, the "seeked" event will fire. So if you were to only pick one (no reason you can't use more), this is the one to pick.

Live sound synthesis in Javascript: any way to reduce latency?

I'm developing a Javascript music app.
Offline rendering works fine, i.e. generate a buffer, play it at a given time using an AudioBufferSourceNode. Timing is almost perfect.
But I need to generate tones that cannot be created using the default nodes of the API. So I put my sound generating logic inside the callback of a ScriptProcessorNode.
I'm fairly certain that the code in my ScriptProcessorNode is fast enough, because once started the sound plays without a glitch for any number of buffer periods that I want - so filling the buffer in time is probably not the issue here. From my experiments I figured out that the onaudioprocess event of the ScriptProcessorNode is fired at regular intervals, not depending on when the processor node was created. This creates unpredictable latency in the app: if the user presses a key right after a callback has started then it waits till the next period to play.
I've created this fiddle to demonstrate it. There is a simple instrument and two buttons to control it. One plays a pre-recorded buffer:
function playBuffer()
{
source = ac.createBufferSource();
source.buffer = buffer;
source.connect(ac.destination);
source.start(0);
};
and the other one plays the same sound but live:
function playLive()
{
processor = ac.createScriptProcessor(4096, 0, 1);
processor.onaudioprocess = function(e)
{
sineStrument.fillBuffer(e.outputBuffer.getChannelData(0), e.outputBuffer.length);
}
processor.connect(ac.destination);
};
Using the first button you can generate a rhythm and hear that it works flawlessly. Using the second button you can't because it takes around 50+ms for the sound to start.
Now notice that the instrument is really simple, I don't think I have a speed of computation issue here. Plus, if you time it right, you can get the live processed sound to play in sync with your clicks - I figure you "only" need to click just before the onaudioprocess callback is called.
The facts that 1) the playBuffer function plays immediately and 2) it is possible to get the correct timing with the playLive function tell me that there should be a technical way to get a ScriptProcessorNode timed right.
How can I do it? How come playing a buffer doesn't have fixed starting times?
I've tried reducing the buffer size of the ScriptProcessorNode too, but sound gets distorted very quickly. Why is it so? If the code in the callback wasn't fast enough wouldn't the sound have glitches after a while? It does not!
Connect your ScriptProcessorNode to a GainNode with gain value initialized to 0. Make the "Play Live" button set the gain value to 1 when pressed, 0 when released.

Flash not responding via javascript API on IE10 on WIN8

I'm trying to achieve the following:
I have a javascript object that fetches two flash objects.
The two flash objects are then added to the page, the first one I set with play=true and
the second one I set with play=false.
I'm presenting the one with play=true right after download, and placing the other with play=false in an hidden container.
When I press the first one it interacts with my javacsript and in turn the js code
hides the first flash div container and changes the second flash (the hidden one)
div container to be shown.
With that being done I also change the play attribute of this flash from false to true so it will start playing.
The two actions, changing DOM visibility and changing the play attribute to true, are done
in two different setTimeout functions (design constraint!).
The issue I have is that on IE10 on WIN8 the flash object doesn't adhere to the play command.
To be more exact with my actions, I'm fetching the flash obj using:
var myObj = document.getElementById("MY_OBJ_ID"), and then I try to set the play to true by doing myObj.Play(); using the standard Play() method flash exposes.
Off course I check that the object exist before excuting the Play().
In addition, after I press the first flash that suppose to set all of the above in motion,
and nothing happens... If I write the same lines manually in the console:
var myObj = document.getElementById("MY_OBJ_ID");
myObj.Play();
Then the movie plays and everything works.
And I'll mention again, this happens only on IE10 on WIN8.
I'll appreciate any assistance with this issue, I'm breaking my back over this and can't figure it out.
Update - 30/06:
I think I figured out the issues somewhat, the play is not occurring indeed.
In IE 10 you can query the flash obj with flashObj.Playing attribute and I see that it's returning false.
In that case I just call the function with setTimeout and every time and check the attribute status until it's true.
But I see that this attribute is not valid in other browser, and in all browsers there's another API function - flashObj.IsPlaying().
Is there a cross-browser implementation that will let me check if a flash object is in playing state or not?
Let's say something like this:
flashObj.TGetPropertyAsNumber("/", 4) >= 1) || flashObj["IsPlaying"]()
It will check if the first frame or even more has already been played, or check if the "IsPlaying" is returning true?
Update - 01/07:
Well, the above method proved to work correctly on all browsers, so my issue is somewhat resolved.
In order to know if the flash player has loaded I need to preform the above check and if the flash isn't loaded I call the function I use to set play again with setTimeout.
But I'm still perplexed from IE10 on WIN8 behavior.
I don't understand why the flashObj.Play() works first time on all browsers first time I call it and in IE10 I need to do setTimeout for this to work.

Categories

Resources