How to draw a first video's frame in canvas? - javascript

I've found several posts like this but none of them work. For example, this post's first answer is a common solution. I made a fiddle based on his fiddle. The problem is it does work if you change the video's position it'll draw the current frame of video. But what I need is the first frame of the video just after I uploaded it. I tried to draw an image when the loadeddata event is fired. According to its description just what I need:
The loadeddata event is fired when the frame at the current playback position of the media has finished loading; often the first frame.
Still won't draw the first frame. Then I tried to draw an image on canplay and canplaythrough events which should work fine. But it didn't.
After some time playing with events, I found a temporal solution if we set a timeout for > 50 ms and try to draw a canvas it'll draw the first frame. But it's not a stable solution.
My thoughts are maybe the problem with buffering but at the same time canplaythrough fires when the user agent can play the media and estimates that enough data has been loaded to play the media up to its end without having to stop for further buffering of content. And it still didn't work.
Any thoughts?

Related

Video, memory management problems in Internet Explorer and Edge from many videos on page causing them to display dark/black and/or not play

We have a page that contains 77 or so video thumbnails. When a video thumbnail is hovered over, video starts playing within the thumbnail space.
A problem occurs after many (8 to 60 depending on the system/browser) of them get hovered over. The video starts playing incorrectly, or not playing. Basically the flat/redundant areas turn all dark. In Edge, this corrects itself after a second or two, but for our client this is very undesirable behavior.
We made an improvement by pausing each video on mouse out by calling pause(), removing the src attribute, and then calling load() on the element with an empty src attribute, like so:
function pauseVideo(e) {
$('video', this).get(0).pause();
$('video', this).get(0).removeAttribute('src');
$('video', this).get(0).load();
}
This clears up some memory, but the issue still occurs, though more of the videos can play before the problem becomes apparent.
I does appear to have something to do with memory, and exposes what appears to us to be a memory leak within the Microsoft browsers. Each video increases memory usage, and the memory never gets cleared, as it seems to in Chrome and Firefox. The problem usually occurs when memory usage approaches somewhere between 600mb to 1gb (depending on system) in the task manager. (Chrome always sits around ~500-550 megabytes.
Firefox sits around ~700-800 megabytes.)
We noticed some variance on when the behavior starts to occur that depends on video cards, but the issue always become present at some point.
All of these videos are showed in multiple places on the page. So one thing I was wondering was if it is possible to share video memory between elements.
There are a couple other issues that may be related. In IE the videos go completely black, and their dimensions change onscreen which can change the page layout.
Here is a related issue, but it is not a duplicate, as it doesn't not provide a question or solution about having to facilitate 80 or so videos on one page: How to properly unload/destroy a VIDEO element
We're testing on IE version 11.228.17134.0 and Edge version 42.17134.1.0, both currently the latest.
The desired functionality originally was for the videos to pause on the frame when the user moused off the video, but right now appears we wont be able to do that if we have to unload the video.
I will be adding more information about this issue throughout the day as it becomes available.
Our team has a script that detects if DOM elements are within the viewable area on the page, e.i. not scrolled above the top or below the bottom. As the user scrolls, the script adds/removes a class, and dispatches custom events for each element that has the behavior added. I was able to leverage this system to pause, remove, and dispose (garbage collect) video elements that are not in view, and then, repopulate them as they come back into view, with the original properties stored in an array of objects associated with each video/thumbnail.
This disposes the video. The function must be called with .call(), like: disposeVideo.call(videoElement);
var disposeVideo = function () {
this.pause();
delete(this);
$(this).remove();
}
It's odd that though delete(this) is a hack, and shouldn't work in any browser, it appears to work in all browsers, according to comments I've read around this issue, and my findings in IE/Edge.
On IE (not Edge) this has a side effect of slowing down page scrolling. This is caused by the our in-view checking applied to 80 items on the page, or if it is to do with re-downloading posters (thumbnail images) and video, because it does appear to not be effectively caching these assets to be immediately (re)available to the renderer.
Another side effect (also in IE) related to the above, is that as you scroll the videos appear blank until assets are re-downloaded. We're opting to use images layered behind the videos in favor of using the poster attribute for the videos elements that get removed. This way there will never be blank video thumbnails onscreen.
Update: It is possible that having two or more video elements onscreen can cause the problem. We resorted to only showing one (which worked 100%) but did not try to determine a likely maximum number of video elements.

cloneNode() makes html video lag and sometimes not render at all

When I click a video, it should animate from its original position to some target position. For reasons, I can't animate the original video element, so I animate a clone which is created by cloneNode(). I just cycle through about 5 videos (which are less than 20 seconds long) and 5 images when clicking. My animation method was causing only the videos to lag and sometimes not render at all while images seemed to be unaffected. I commented out all of my animation code except for a single line:
var clone = videoElement.cloneNode( false );
Without the animation code, the images/videos just teleport to the target position instantly (which is expected). But leaving that single line uncommented, when I click relatively quickly, causes the videos to lag a little (if I'm lucky) and sometimes not render at all in Chrome. In Edge, the videos take a few seconds to render. Removing that line, the videos load/render just fine no matter how fast I click.
Why does this happen? Is cloneNode really just that slow?
Are there any practical solutions to this problem?
It seemed like the problem was with cloneNode(), but it turns out it was because I was using mp4 files as the source for my videos. mp4 is deprecated in Chrome. As soon as I converted to webm video files, the lag/rendering problem completely disappeared.

Show loading image when video buffer next frames

I' using html5 video. I need to show the loading image when video buffering next frame like a youtube when video is stop and downloading next frames youtube show a loading image which is circle gif image and when video download enough frame to start it loading image disappear.
I'm not asking about first time video start.
I know I can use poster while video is not starting or I can use event loadstart and canplay.
These things work fine when video is starting first time. But problem is that I want loading image when video is stop while playing due to buffering next frame.
So, what I event use or how can I do this.
Thanks.
To achieve this, you may want to listen to the corresponding events from the video element. A list of available events can be found at w3schools.com.
The two events of interest for your goal are stalled and waiting, once they are fired you can display your loading animation.

html5 video seek performance

I'm writing a simple app to seek an html5 video in both directions by dragging mouse. I also need to overlay stuff on top of the video so I'm using html5 canvas. The video element stays hidden, I play the video and update the canvas image every 20 ms. This much has no performance issues.
However I want to seek the video when I drag the mouse. It turns out that I would need to seek the video every 20 ms which leads to a choppy performance. Another hack I tried was to fast forward the underlying video when I drag. This has almost perfect performance and is sufficient for my use case except I can't rewind and fast-forward the video.
My research says the only way right now to rewind an html5 video is to set the currentTime backwards frame by frame, but again I can't afford to do this every 20ms or the video gets choppy.
Is there any way around these limitations? It would be enough if I can just play the video backwards in normal speed.

Video Networkstate InternetExplorer

I'm trying to create a video with slides next to it using HTML5 and Javascript.
The problem with InternetExplorer is that it's video networkstate stays on 2 for a while. As long as it is downloading the video, it won't be downloading my slides next to the video.
As a fix I tried pausing the video if the preloaded image isn't loaded on the time it has to pick over the slides' spot. But however the video stays downloading (Taking about 300 seconds according to the network state) And once it's done the slides will load directly. (Taking 260 seconds according to the same thing, but as soon as the video is loaded they ARE loaded)
When ever I try to use myVideo.networkState in the console I get state 2(loading) when it's not working, and state 1 when it does. So it has something to do with the video.
So the question:
Is there a way to either give priority to the slides, so they WILL load
Or a way to let IE download both slides and video on the same time.
Or giving the video a limited speed, if this has to do with a speed problem.
Answer: Delete Internet Explorer, Download Google Chrome.

Categories