Rendering a chain of images like a video in javascript
I'm trying to synthesize a video using a stream of images in JavaScript. The problem is the "v开发者_如何学Pythonideo" is either jerky, which was solved by using a buffer of sorts. However now the problem is that images are actually downloaded far faster than they are rendered.
If you have a source of images that changes, like an IP camera you can try the example below. What I have noticed is that, the "video" still updates quite slowly, however while watching a packet sniffer I can see that the image is actually being fully retrieved far faster than it is being rendered.
Here is the example:
<HTML>
<HEAD>
<SCRIPT SRC="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js">
</SCRIPT>
<SCRIPT>
function startVideo()
{
//when the buffer image is loaded, put it in the display
$('#image-buffer').load(function()
{
var loadedImage = $(this).attr('src');
$('#image-displayed').attr('src', loadedImage);
$(this).attr('src',
'http://path.to/image.jpg?nocache=' + Math.random());
});
$('#image-buffer').attr('src',
'http://path.to/image.jpg?nocache=' + Math.random());
}
function stopVideo()
{
$('#image-buffer').unbind('load');
$('#image-buffer').attr('src', '');
$('#image-displayed').attr('src', '');
}
</SCRIPT>
</HEAD>
<BODY>
<BUTTON ONCLICK="startVideo();">Start Video</BUTTON><BR/>
<BUTTON ONCLICK="stopVideo();">Stop Video</BUTTON><BR/>
<IMG ID="image-displayed"/>
<IMG ID="image-buffer" STYLE="visibility: hidden;"/>
</BODY>
</HTML>
Your video will almost certainly be jerky, unless the size of the images are guaranteed to be consistent in some way. And even then, the loading of the images will be dependent on the network conditions. About your problem of the script loading images faster than they are displayed, there's no way to determine the source of that, unless we get actual access to your source.
Rewriting the code using the Stack Exchange API as the image source, and monitoring activity using Firebug we can see that the network activity roughly match what we see on screen.
The code used is:
$('#buffer').load(function(){
$('#video').attr('src', this.src);
this.src = sites[Math.floor(Math.random() * sites.length)].logo_url + '?cache=' + new Date().getTime();
}).trigger('load');
See this code working live here: http://www.jsfiddle.net/yijiang/r957s/
Searching for a solution myself. Here is a nice little article about doing something amazingly convenient for IP camera case.
http://techslides.com/convert-images-to-video-with-javascript
Also try loading all images in an image strip (CSS stuf) (assuming that there would not be a large amount of images) and hide all but first with overflow: hidden. Then change image strip position for the width of the image with setInterval (basically a very quick slider without any transition animations). In that case all images would be already loaded AND rendered and you can control timing between each "frame".
I had a similar problem (in firefox-not an issue in other browsers.) In the end I litterally downloaded my movie as a filmstrip, put it it in an overflow hidden div and offset the image by the height of a frame. Saves a few k on total file size to boot! I made my filmstrip with gdlib
Instead of loading images as often as possible, you can use the window.setInterval
method to make a function run at a set interval, for example ten times a second.
You can start loading the next image as soon as you have displayed an image, but instead of having the load event showing it, you can let the function that is running at an interval do that.
精彩评论