APNG gets out of sync after second page refresh - javascript

I have an app with an animated UI realised via APNG images.
Each block has 2 APNG images and one PNG one:
Appearing (APNG)
PingPong (APNG)
Static (PNG)
I need to play the second animation right after the first one is finished and only make visible the PNG image after a touch event. I've done it via setTimeout but, unfortunately, after second page refresh a browser completely ignores some animations, some of them start jittering, some disable in an inappropriate moment.
How can I fix the problem?
And can I catch the moment when APNG animation has finished? Do APNG images emit any events?
To check the problem, open the app on mobile device and scan the code.

Browsers don't have any built-in support for treating APNGs as anything other than an image: there is no way to determine when an APNG has started or stopped playing. You could probably fix the issue by just converting the APNGs to an actual video file format, and embedding the images with <video> instead, since that has an API for controlling playback. Alas, it doesn't seem that any browsers support treating APNGs as video so you'll need to convert it to another video format, such as WebM.
If you are really committed to not converting your APNGs to a video file format, you could work around the limitation in browsers by using a library such as pngjs to decode the APNG, extracting the fdAT chunks, and then manually animating through those extracted frames (each frame in an APNG is itself a (non-animated) PNG).

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.

smooth video transition HTML5

looking to use HTML5 video tag and JS. the aim is to make a video swap from one video to the next very smoothly just like a cut in the movie. I have had a look at the API
http://www.w3.org/TR/html5/video.html#tracklist
if anyone has an idea that would be great. My current plan is to familiarise myself with the API and figuare out how to que up the video for a smooth change. currently sellect a src and then play() causes an ugly white space pause before the next video comes in.
many thanks for looking
Use firefox and make hardware acceleration on. if you have good hardware it should work.
and you can also try this method, imagine if you have 5 videos to play and when you are in the 2nd video you can keep them by the video currently you are playing ,keep them on left and right sides and make them pause. when you move on to the 3nd video you can just get that relevant video and make it play. this method should eliminate any unnecessary lags.
HTML5 videos use a very low amount of CPU, so there's no reason you can't have multiple tags on the page at the same time. I would suggest having them all on the page and then using CSS and JavaScript to transition between them.
You won't be able to make this work on iOS since it doesn't allow playback to initialize without user interaction. The user will have to click to start each video.
Annoying, but that's how Apple rolls.

Speeding up HTML5 video seek?

Hey all I wonder if you guys know some trick that could help me out. What I have implemented is a slider that controls the seek position of an HTML5 video via the currentTime property. What I would like to have happen is as the user is dragging the slider the video is updating in real time.
What I have works but the video players image doesnt update to each frame as I set the current time. Any thought?
slide: function(e, ui){
seeksliding = true;
$gVideo[0].currentTime = ui.value;
},
Modern browsers are generally very good at seeking quickly, even to the point where you can synchronize two or more videos using Javascript, with the same kind of functionality you're describing. (Firefox around version 4-5 would take a few extra milliseconds and lose sync, but it's better now.)
The code you have should work, as long as ui.value is between zero and the duration of the video. But you may run into problems if a) the video is not loaded or b) there is something up with the encoded video file.
First, make sure the browser can play the video and seek without any Javascript controls. Just try opening up the file in the browser, first straight off your hard drive and then off the network. If you can't seek with the native controls, you can't seek with Javascript. I've sometimes seen seeking errors solved by re-encoding a video without B-Frames.
Next, see if the video is loaded when you're trying to seek. You can speed this up by adding a preload attribute to the video tag. And make sure the slider event isn't enabled until the browser has the video's duration, by putting the slider code inside a loadedmetadata event.

Cache images offscreen in Mobile Safari

I have an javascript image gallery that slides in images from offscreen in Mobile Safari. It seems like the offscreen images are not getting cached because every time they slide in it takes a few seconds to load them at which point they are already halfway to their destination. I'm trying to get all the images to load during the initial page load. It seems Mobile Safari ignores or "garbage collects" offscreen images. Is there a way through CSS3 (some -webkit prefix property) or any way so that all images load and stay loaded so their is no flickering.
Thanks!
If the set of images in the gallery is somewhat static (ie. it's managed through some sort of upload process rather than picking up images dynamically), you could try using an HTML5 offline application cache for your images. This blog post describes the technique, along with some other pitfalls frequently encountered with iPhone caching.

Categories