HTML5 video with seamless loop within video - html5-video

I am programming an interactive video (kind of game) where the user make actions on a side panel and actions happens in the video.
For a part, the video is waiting for user action on the panel, so it has to loop until the action has been launch by the user.
So at 15 seconds, I get back to 11 seconds as long as the user has not made the action, video is designed to be a perfect loop.
My loop is working, but the problem is thats it's not seamless. At 15 seconds, it stops for like a second, and then starts back at 11 seconds. Is there a way to make it work seamless?
I am using VideoJS. Here is my code:
var video_decor = _V_("video_decor");
video_decor.addEvent("timeupdate", function(){
var whereYouAt = video_decor.currentTime();
console.log(whereYouAt);
if(whereYouAt > 15){
video_decor.currentTime(11);
}
});

The easiest way to do a seamless loop is by using a full length video and waiting for the 'ended' event to go back to the beginning. That tends to be pretty smooth, so if you can make that happen some how that'd be best.
Taking a sub-section of the video and looping it is difficult, because browsers don't trigger the 'timeupdate' event every millisecond, and it would be really inefficient to do so. They instead trigger timeupdate every 15 (Chrome/Safari) or 250 (Firefox) milliseconds, so that's your margin of error. You could potentially create your own timer (setInterval) for a smaller interval and check the time manually, but that could put a heavy load on the browser.

Related

React-native: Execute post request after 20 seconds, even if app goes on backgound

When app runs in foreground, i execute successfully a POST-request using setTimeout with 20 seconds like this:
setTimeout(function() {
/*POST request is done here*/
}, 20000);
Though, if in meanwhile user places the app on background, by pressing home button for example, then my post won't get fired after 20 seconds.
On Android though, i checked that if 20 seconds get passed, and then i open the app(make it be in foreground), then post is executed immediately. (Haven't tested on ios to see if same thing happens). So i have the following questions:
1) Same behavior is happening on IOS side too?
2) Should i expect exactly same behavior if timeout had 15 mins timer and not 20 seconds?
3) How can i solve this problem? I need to contact to an endpoint after some time, and can't do it while app is in background with setTimeout.
Using libraries like react-native-background-task do not help in this situation, as i need to execute code after exactly 20 secs(or 10 mins etc) and not some time in future like 15 mins+
try this library it sets time what you want to set, but remember ios won't allow the time more than 30 sec
https://github.com/ocetnik/react-native-background-timer
I've had same kind of problem, and I used react-native-background-timer and it worked perfectly for Android.

Random high content download time in chrome?

We have an API which randomly takes high content download time in chrome, It works fine always in firefox and takes an only few ms. The response size is 20kb uncompressed and 4kb compressed. The same request also works fine using curl.
Things that we have tried:
Disabling If-None-Match header to disable cache response from the browser.
Trying various compressions (gzip, deflate, br).
Disabling compression.
Disabling all chrome extensions.
The same request works fine sometimes on chrome but randomly returns very high content download time.
We are unable to understand the root cause of this issue. What are the other things we can try to minimize this time?
I made three requests here and the 3rd one took the most time (before the last spike). CPU does not seem to be maxing out for a longer period of time. Most of the time is idle time.
Also, When replaying the call using Replay XHR menu, the Content download period drops from 2s to 200 ms.
Are you by chance trying to implement infinite scrolling? If you are, try dragging the scroll bar instead of using the mouse wheel. For some reason, Chrome seems to struggle with mouse scroll events. If the scroll bar worked just fine, keep reading.
This post provides a detailed walkthrough of someone experiencing something similar - https://github.com/TryGhost/Ghost/issues/7934
I had attached a watcher on the scroll event which would trigger an AJAX request. I had throttled the request and could see that only 1 was being sent. I watched my dev server return the response within a few ms but there would be a 2 second delay in chrome. No render, no api calls, no and scripts executing. But the "Content Download" would take 3 seconds for 14kb. No other browser had this issue.
I stumbled upon suggestions that using requestAnimationFrame instead of setTimeout would solve the problem. That approach seems that approach works when the "Waiting" or green is significant, not so much for the "Content Download" or blue.
After hours of digging, I tried conditionally calling e.preventDefault() on the mousewheel event and to my amazement, it worked.
A few things to note:
1) I did not use the mousewheel event to make the api call. I used the scroll event along with throttling.
2) The mousewheel event is non-standard and should not be used. See https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel
3) BUT in this case, you have to watch and handle the mousewheel event because of chrome. Other browsers ignore the event if they don't support it and I have yet to see it cause an issue in another browser.
4) You don't want to call preventDefault() every time because that disables scrolling with a mouse :) You only want to call it when deltaY is 1 if you are using vertical scroll. You can see from the attached image that deltaY is 1 when you basically can't scroll anymore. the mousewheel event is fired even though the page cannot scroll. As a side note, deltaX is -0 when you are scrolling vertically and deltaY is -0 when scrolling horizontally.
My solution:
window.addEventListener("mousewheel", (e) => {
if (e.deltaY === 1) {
e.preventDefault();
}
})
That has been the only solution that I've seen work and I haven't seen it mentioned or discussed elsewhere. I hope that helps.
console log of mousewheel event
I think you may be doing it wrong.™
Fundamentally, if this really only happens with Chrome, then perhaps the client-side code is to blame, of which you don't reveal any details.
Otherwise, you are trying to debug what you present as a backend condition (based on the choice on the nginx tag) with front-end tools:
Have you tried using tcpdump(8) to troubleshoot the issue? What packets gets exchanged and at what times?
Have you tried logging the times of the request being received and processed by nginx? E.g., $request_time?
Where is the server located? Perhaps you're experiencing packet loss, which may require timeouts and retransmission of some TCP packets, which invariably will introduce a random delay?
Finally, the last possibility is that the field doesn't mean what you think it does -- it sounds like it may take a hit from CPU load, as this is the result of the XMLHTTPRequest (XHR) processing -- perhaps you run some advertising with user tracking that randomly consumes a significant amount of CPU, slowing down your metrics?

Safari html5 video timeupdate event gets disabled

We are playing videos from a server. We attach an 'ontimeupdate' event which fires periodically, as the video plays. For slow connections, we can compare where the video currently IS, to where it SHOULD be. Then we can do some other things we need to do, if it is lagging. Everything works fine in Chrome, FF, IE. In Safari, when the connection is slow, the event only fires twice. Why does it get removed? Is there a way to add the event again, inside of the handler for the event? Thanks
The HTML5 audio/video element is still less than perfect. The biggest issues I've noticed is that it doesn't always behave the same way in every browser. I do not know why the timeupdate event stops firing in Safari, but one option you have is to monitor whether the video is playing or not and verifying the information independently. Example,
$(video).bind('play', function() {
playing = true;
}).bind('pause', function() {
playing = false;
}).bind('ended', function() {
playing = false;
})
function yourCheck() {
if (playing) {
if (video.currentTime != timeItShouldBe) {
//do something
}
} else {
return;
}
setTimeout( yourCheck(), 100);
}
Something to that effect. Its not perfect, but neither is the current HTML5 audio/video element. Good luck.
The event will not fire if the currentTime does not change, so it may not be firing if the video has stopped playing to buffer. However, there are other events you can listen for:
1) "stalled" - browser is trying to load the video file, but it's not getting anything from the network.
2) "waiting" - playback has stopped because you ran out of buffered data, but it will probably pick up again once more data comes in from the network. This is probably the most useful one for you.
3) "playing" - playback has resumed. Not to be confused with "play" which just means it's "trying" to play. This event fires when the video is actually playing.
4) "progress" - browser got more data from the network. Sometimes just fires every so often, but it can also fire after it recovers from the "stalled" state.
See the spec for reference.
I've heard some people say that these events can be unreliable in some browsers, but they seem to be working just fine here: http://www.w3.org/2010/05/video/mediaevents.html
If you want to be extra cautious, you can also poll periodically (with a timeout as tpdietz wrote) and check the state of the video. The readyState property will tell you whether you have enough data to show the current frame ( >= 2 ), enough to keep playing at least a little bit into the future ( >= 3 ) or enough to play all the way to the end (probably). You can also use the buffered property to see how much of the video has actually been buffered ahead of where you're playing, so you can roughly estimate the data rate (if you know how big the file is).
MDN has a great reference on all these properties and events.

Why don't Chrome and Firefox fire events when a video begins buffering?

The MediaElement.js library for HTML5 video is the most complete option that I have found, and also the only one I can use on this project.
The problem is that when the videos load poorly over a slow connection, neither the video element or the MediaElement library dispatch an event when the video stops playing and begins to buffer. This is only happening in Chrome and Firefox.
I have added event listeners to the stalled, waiting, and suspended events, and none of them are fired when the video pauses to buffer in Chrome or Firefox.
Any ideas? Any help is greatly appreciated.
Thanks!
If you look at the code for MediaElement.js, you'll notice the stalled and suspended are not set for MediaElement object. Waiting wouldn't work because it's called when the playback is waiting on another operation (e.g. seek)
waiting: Sent when the requested operation (such as playback) is delayed pending the completion of another operation (such as a seek). https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
This is not tested, but you can try the following
Set a playing event that will create an interval to check the current
time of the video. If the video current time didn't change from last interval, than
most likely the video is buffering or not loading.
Set a pause event to clear the interval.
You might need to set other events to make sure the event
is not triggered by user actions.
Hope this helps.

Application getting slower and slower when navigating

I'm building a Windows Phone application that does video capture in a page and has a custom player in another page. I'm using my own custom codec so the player needs a lot of DispatcherTimer to keep track of several behaviors on the UI part and serve the movie at the good framerate in the codec part.
I'm trying to release all DispatcherTimer as I know they are CPU intensive, but even when stopping them my app is still very slow. If I press back-back then follow the flow, the speed divides by two each time. If I don't use my player, eveything is ok. And my player is only made of 3 DispatcherTimer, a FileStream and an Image box.
I feel that DispatcherTimer are still running in memory and are double-instantiated even if they are instantiated as private on the page directly.
Can I force the page to release all this stuff?
Actually I don't understand yet what is the difference between navigating to a page next to current page, or navigating back. I don't know i.e. how the page is shown again without calling InitializeComponents, so I'm mixed up about which resources to release, and which resources to keep intact.
My execution speed problem was really caused by some running DispatcherTimer, so I'll answer it to have it archived.
The solution:
Ensuring that all DispatcherTimer has been instantiated directly on the page so that we can nullify them from anywhere in the code.
In OnNavigatedFrom, I kill the DispatcherTimer and in OnNavigatedTo, I recreate them with myDispatcherX = new DispatcherTimer();
No "temporary" timers, like "DispatcherTimer myTempTimer = new DispatcherTimer; with ((DispatcherTimer)send).Stop() in callback, as chances are that it remains in memory in an application where we navigate.