Canvas vs Image for faux video player-Collection of common programming errors
I have a server that generates pngs very rapidly and I need to make this into a poor-man’s video feed. Actually creating a video feed is not an option.
What I have working right now is a recursive loop that looks a little like this (in pseudo-code):
function update() {
image.src = imagepath + '?' + timestamp; // ensures the image will update
image.onload = function () {update()};
}
This works, however after a while, it crashes the browser (Google Chrome, after more than 10 minutes or so). These images are being updated very frequently (several times a second). It seems the images are caching, which causes the browser to run out of memory.
Which of these solutions would solve the problem while maintaining fast refresh:
- HTML5 canvas with drawImage
- HTML5 canvas with
CanvasPixelArray
(raw pixel manipulation)
I have access to the raw binary as a Uint8Array, and the image isn’t too large (less than 50 kb or so, 720 x 480 pixels).
Alternatively, is there anyway to clear old images from the cache or to avoid caching altogether?
EDIT:
Note, this is not a tool for regular users. It’s a tool for diagnosing analog hardware problems for engineers. The reason for the browser is platform independence (should work on Linux, Windows, Mac, iPad, etc without any software changes).
-
The crashing is due to http://code.google.com/p/chromium/issues/detail?id=36142. Try creating object URLs (use XHR2
responseType = "arraybuffer"
along withBlobBuilder
) and revoking (usingURL.revokeObjectURL
) the previous frame after the next frame is loaded.Edit: You really should be processing these into a live low-fps video stream on the server side, which will end up giving you greatly decreased latency and faster load times.
-
@Eli Grey seems to have identified the source of your crashing. It looks like they have a fix in the works, so if you don’t want to modify your approach hopefully that will be resolved soon.
With regard to your other question, you should definitely stick with
drawImage()
if you can. If I understand your intention of using theCanvasPixelArray
, you are considering iterating over each pixel in the canvas and updating it with your new pixel information? If so, this will be nowhere near as efficient asdrawImage()
. Furthermore, this approach is completely unnecessary for you because you (presumably) do not need to reference the data in the previous frame.Whether fortunately or not, you cannot directly swap out the internal
CanvasPixelArray
object stored within an HTML5 canvas. If you have a properly-formatted array of pixel data, the only way you can update a canvas element is by calling eitherdrawImage()
orputImageData()
. Right now,putImageData()
is much slower thandrawImage()
, as you can see here: http://jsperf.com/canvas-drawimage-vs-putimagedata. If you have any sort of transparency in the frames of your video, you will likely want to clear the canvas and then usedrawImage()
(otherwise you could see through to previous frames).Having said all that, I don’t know that you really even need to use a canvas for this. Was your motivation for looking into using a canvas so that you could avoid caching (which now doesn’t seem to be the underlying issue for you)?
-
If the “movie” is data-driven (ie. based on numbers and calculations), you may be able to push MUCH more data to the browser as text and then have javascript render it client-side into a movie. The “player” in the client can then request the data in batches as it needs it.
If not, one thing you could do is simply limit the frames-per-second (fps) of the script, possibly a hard-coded value, or a slider / setable value. Assuming this doesn’t limit the utility of the tool, at the very least it would let the browser run longer w/o crashing.
Lastly, there are lots of things that can be done with headers (eg. in the .htaccess file) to indicate to browsers to cache or not cache content.
-
iPad, you say ?.. Nevertheless, i would advice using Flash/video or HTML5/video.
Because WebKit is very easily crashed with even moderate influx of images, either just big images or just a huge number of small ones..
From the other side, XHR with base64 image data or pixel array MIGHT work. I have had short polling app, which was able to run for 10-12 hours with XHR polling server every 10 seconds.
Also, consider delta compression, – like, if its histogram with abscissa being time scale – you can only send a little slice from the rigth, – of course, for things like heat-maps, you cannot do that.
These images are being updated very frequently (several times a second).
.. if its critical to update at such a high rate – you MUST use long polling.