6

Question

I want to write efficient code for playing/manipulating images in a web browser using JavaScript. I think using a video file may cut down http requests. How can I access a png/jpg/bytecode version of a single frame from a video?

Background

Currently, I have a sequence of ~1000 images, which vary ever-so-slightly, that need to be quickly accessible on my page. loading the images via HTTP requests is taking forever(obviously), and as my app grows, it is likely that this number will grow from 1000 to 5000 to 10,000 ...

Ajax requests for individual images will not work, b/c I need the image to load immediately (and don't have time to wait for a new http request).

My idea was to pre-process a video file on the server which shows the image progression- one image per frame-to speed up the rate of download and the browser's performance. I feel like this video could download to the client quickly based on the speed of watching videos online. I'm getting stuck on how to get picture content for a frame out of the video.

HTML5?

Note, I haven't looked into HTML5 yet, but would be willing to consider if it may help.

Rishi
  • 3,538
  • 5
  • 29
  • 40
  • 1
    Since the images vary only slightly from image to image, some video compression formats only save the differences between the frames making the video smaller in size than all the individual frames, or so I believe. Also, fewer http requests would be required to download a movie – Rishi Apr 15 '12 at 18:32

2 Answers2

14

You can draw video frames to html5 canvas.

I created this fiddle by combining this and this.

Key point is getting the current video frame and drawing it into the canvas element.

var delay=20;
function draw(cvideo,ccanvas,canvas_width,canvas_height) {
  if(cvideo.paused || cvideo.ended) return false;
  ccanvas.drawImage(cvideo,0,0,canvas_width,canvas_height);
  setTimeout(draw,delay,cvideo,ccanvas,canvas_width,canvas_height);
}

After getting it into canvas you can do almost anything with the image.

Community
  • 1
  • 1
username
  • 4,258
  • 1
  • 16
  • 26
  • I like this suggestion. Furthermore, it seems like I can skip ahead to a particular frame using by setting the currentTime: "video.currentTime = starttimeoffset;" based on http://blog.gingertech.net/2009/08/19/jumping-to-time-offsets-in-videos/ – Rishi Apr 18 '12 at 02:21
  • Best Answer and Bounty because it specifically answers the question I asked – Rishi Apr 18 '12 at 02:22
  • is it possible to get the frames directly form the video file instead of using – Chaitanya Apr 18 '15 at 08:07
  • @ChaitanyaChoudhary marvelous question. I have no idea. :) I suppose with video tag we are using browsers video encoders. Maybe you can also try to use ffmpeg over node.js. But it would add quite an overhead. But again, i think video tag is supported on all modern mobile OS'es. http://caniuse.com/#feat=video – username Apr 20 '15 at 11:44
  • yo do u also know if theres a way to get the current audio as some kind of arraybuffer? – B''H Bi'ezras -- Boruch Hashem Mar 27 '19 at 11:51
2

Instead of using a video file you could use image sprites - basically combine multiple images into a single big image, of which you only always show the appropriate region (assuming all images have the same dimensions this would be easy) - this would largely reduce the number of necessary HTTP requests and speed up the loading process in turn.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • Good idea, this does cut down HTTP requests, but it doesn't cut down the total amount of information that needs to be downloaded - See my comment. – Rishi Apr 15 '12 at 18:38
  • @Rishi, images combined into a sprite will weigh much less than original images and doing 1 long http request will be much shorter than 1000 short ones combined so... – Headshota Apr 15 '12 at 18:57
  • Sprites seem like a great method, and may be a good alternative if username's solution does not work. Thanks for the advice though. – Rishi Apr 18 '12 at 02:24