2

When using <video id="videoID"> </video> (HTML),

you can use canvas = document.getElementById('canvas') in the script (Javascript)

and videoID.play() or videoID.pause().

If my video is streaming from a URL (as webcams do) as an <img src="http://ip_address/stream"> tag, I can't use the .play() or .pause() functions. Can I still use:

    canvas = document.getElementById('canvas');

    var context = acontainer.getContext('2d');
    context.drawImage(acontainer, 0, 0, width, height);
    var data = acontainer.toDataURL('image/jpeg');
    photo.setAttribute('src', data);

The goal is to get a picture of the video stream when I click - so I have a mouse click event that does the above.

How can I do this?

More info: This page has URL http://ip_address and video stream has URL http://ip_address/stream. The video stream is <img> -lots of jpeg images being streamed- within a <div> container, e.g. Code looks like-

    <!DOCTYPE html>
    <html>
    <head>
    ...
    <style>
    ...
    </style>
    </head>
    <body>
        <div id="container">
            <img src=...>
        </div>
    <script>
        container.addEventListener("click", function(element){}, false);
    ...
    </script>
    </body>
    </html>

EDIT: This question is not a duplicate as I'm not asking how to stream to a html canvas. Rather, I already have a stream displaying in a container and I want to take a photo of it and have it appear in a canvas - so the stream and photo appear on the same page.

  • Pass `` element reference as first parameter to `.drawImage()`. Why do you not use ` – guest271314 Feb 14 '17 at 19:45
  • Is `"http://ip_address:port"` resource served with `Access-Control-Allow-Origin` header? – guest271314 Feb 14 '17 at 19:52
  • When I use `` I get an error. I'm live-streaming from a webcam, so the format is `` right? So you're saying I should have `context.drawImage(img_ID, 0, 0, width, height);` – FullMetalScientist Feb 14 '17 at 19:52
  • What is error do you get at ` – guest271314 Feb 14 '17 at 19:55
  • @guest271314 I don't have a header, I use a proxy server so I can access the stream from another port (URL of stream `http://ip_address/stream`). Actually, the URL of the webpage all of this is on is just `http://ip_address` without the port number - I will edit the question. – FullMetalScientist Feb 14 '17 at 19:55
  • @guest271314 when I change `` to `` and test it on the web browser, I get the errors: `HTTP “Content-Type” of “multipart/x-mixed-replace” is not supported. Load of media resource http://ip_address/stream failed. Cannot play media. No decoders for requested formats: multipart/x-mixed-replace` – FullMetalScientist Feb 14 '17 at 20:05
  • Have you tried `canvas` approach? Can you create a stacksnippets or plnkr http://plnkr.co to reproduce stream at `` element? – guest271314 Feb 14 '17 at 20:10
  • Yeah, I have a `` and the photo, when I click should appear in a `
    `. Then the `context.drawImage` part happens. I can't really reproduce the stream, it's not currently connected to a camera but still streams with the time changing. If you've heard of 'motion', it's streaming via that.
    – FullMetalScientist Feb 14 '17 at 20:24
  • Yes, `motion` can save images to a filesystem itself, yes? What to you mean by _"when I click should appear in a `
    `should appear"_? If `` elements is already rendering streaming images from `motion`, what are you trying to achieve? Are you trying to capture a still image from the stream and display that capture at a different `` element?
    – guest271314 Feb 14 '17 at 20:28
  • Yes, `motion` can. I mean, when I click the container containing the video stream, a still photo from the video stream should be captured and shown, this photo has the id `photo`. Yes, your last sentence- that's what I'm trying to achieve :) – FullMetalScientist Feb 14 '17 at 20:49
  • @Kaiido Not a duplicate. `motion` does not stream `mjpeg` by default, but rather creates static image files. The `` element OP is describing is being updated by pointing to a static image file, not streaming at ` – guest271314 Feb 15 '17 at 04:13
  • @guest271314, from [motion's homepage](http://www.lavrsen.dk/foswiki/bin/view/Motion/WebcamServer) : "*The webserver generates a stream in "multipart jpeg" format (mjpeg).*". If it were static jpegs, how would the browser know that it has to fetch again ? – Kaiido Feb 15 '17 at 04:16
  • @Kaiido Well, from own experience with `motion`, static images were save at a filesystem, not streamed. What do you mean by "fetch it again"? Thousands of images can be created. Set `` `src` to last captured image. – guest271314 Feb 15 '17 at 04:18
  • @guest271314, yes probably on server it does save static jpegs, before creating the mjpeg stream. There is no way a server can tell "Hey download me again in *x* ms !" to the browser, except if it's a known streaming format. – Kaiido Feb 15 '17 at 04:19
  • @Kaiido Did not use an `mpeg` stream when used `motion`. The captured images were stored as flat files at a filesystem. Get the last image path to set at `img` `src` at the duration you set, for example using `cron`, if requirement is to display the captures in such fashion. Again, `motion` configuration is beyond the scope of present Question. OP has mentioned they have not yet captured any images thus far. – guest271314 Feb 15 '17 at 04:21
  • @Kaiido Where do you see OP mentioning `mjpeg`? Though, if you believe the Question to be a duplicate, your vote is your own to do with as you will. If anything, the Question is not entirely clear as to what approach is actually being implemented, nor if there are any issues with the approach; as OP has not actually captured any images, yet, from what can gather so far from exchanges at comments. – guest271314 Feb 15 '17 at 04:27
  • 1
    @Kaiido Not sure why you considered this Question a duplicate of linked Question? OP not trying to stream to `canvas`. OP is trying to capture a still image from a stream, or the current `src` of an `` element, then create a still image from that capture at `click` event. fwiw, was able to use approach at Answer to capture a static image from `mpeg` stream at link as `data URI` without any issues. – guest271314 Feb 15 '17 at 04:48
  • @guest271314 because you are relying on [a chrome bug](https://bugs.webkit.org/show_bug.cgi?id=74779), linked in the accepted answer of the target dupe... We're not helping OP nor any future readers here... Quit conversation. – Kaiido Feb 15 '17 at 04:59
  • @Kaiido Well, you begot conversation. You can "quit" at your own calling. Still trying to gather what you are describing. _"So once you fetched the data, only one frame should be drawn onto the canvas."_ That is what OP is expecting at the present Question. – guest271314 Feb 15 '17 at 05:05

1 Answers1

1

Set .getContext("2d") should be called on canvas element, not acontainer; pass img reference as first parameter to .drawImage() instead of acontainer; .toDataURL() should be called on canvas element, not acontainer.

var blue = "data:image/png;charset=binary;base64,iVBORw0KGgoAAAANSUhEUgAAASoAAADCCAYAAAD+Wo90AAAABHNCSVQICAgIfAhkiAAAApVJREFUeJzt1DEBACAMwLCBf88ggZMeiYJeXTPnDEDY/h0A8GJUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkGdUQJ5RAXlGBeQZFZBnVECeUQF5RgXkGRWQZ1RAnlEBeUYF5BkVkHcBRH8DgsmlTc8AAAAASUVORK5CYII=";

var red = "data:image/png;charset=binary;base64,iVBORw0KGgoAAAANSUhEUgAAAScAAADACAYAAABGbKXPAAAABHNCSVQICAgIfAhkiAAAAo5JREFUeJzt1DEBACAMwLCBf89ggJ8eiYJeXWfmDEDM/h0A8GJOQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSeYEJJkTkGROQJI5AUnmBCSZE5BkTkCSOQFJ5gQkmROQZE5AkjkBSRfjxQN+R4GWHgAAAABJRU5ErkJggg==";

var green = "data:image/png;charset=binary;base64,iVBORw0KGgoAAAANSUhEUgAAAScAAADBCAYAAACNMHZqAAAABHNCSVQICAgIfAhkiAAAApJJREFUeJzt1DEBwCAQwMCnynEOBrqT4U5BpqzZcwYg5nsdAPDHnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUgyJyDJnIAkcwKSzAlIMicgyZyAJHMCkswJSDInIMmcgCRzApLMCUi6PDoDAbyCsn8AAAAASUVORK5CYII=";

var arr = [red, blue, green];

var img = document.querySelector("img");

var button = document.querySelector("button");

var containerImg = document.querySelector("div > img");

var canvas = document.createElement("canvas");

canvas.width = canvas.height = 100;

var ctx = canvas.getContext("2d");

var i = 0;

button.addEventListener("click", function() {
  ctx.drawImage(img, 0, 0)
  containerImg.src = canvas.toDataURL();
});

setInterval(function() {
  img.src = arr[i];
  i = ++i % arr.length;
}, 100);
<button>capture image</button><br><br>
<img width="100" height="100" alt="stream"/>
<br><br>
<div>
  <img width="100" height="100" alt="capture"/>
</div>
guest271314
  • 1
  • 15
  • 104
  • 177
  • Oh wow, nice! I will look into this. Your code works like I want it. – FullMetalScientist Feb 14 '17 at 21:01
  • So I have: `var ctx = canvas.getContext('2d'); ctx.drawImage(videoID, 0, 0, width, height); var data = canvas.toDataURL('image/jpeg', 1.0); photo.setAttribute('src', data);` On the web browser, no errors but it doesn't show the photo, just the stream with the time updating every second - unless this is meant to happen since `motion` is not currently connected to a webcam? I thought the grey screen with the time would get captured. – FullMetalScientist Feb 14 '17 at 21:13
  • Not sure what you mean? What is `videoID`? Are you using ` – guest271314 Feb 14 '17 at 21:15
  • By `videoID` I meant `img_ID`, sorry. It is from the HTML part: `
    ` so I'm not using a `
    – FullMetalScientist Feb 14 '17 at 21:19
  • Oh and by time changing - I mean, the stream currently shows a grey screen with the current time at the bottom, which updates every second. I image that when I do the image capture, that I should only see a still image (where the time is not changing). But perhaps, since there is no webcam connected, that no image is captured and so is not showing at all? Hence, I am still seeing the video stream. – FullMetalScientist Feb 14 '17 at 21:27
  • Are you able to capture image using `html`, `javascript` at Answer? – guest271314 Feb 14 '17 at 21:28
  • Debugging `motion` configuration and associated hardware is perhaps beyond scope of original Question? – guest271314 Feb 14 '17 at 21:38
  • You mean if the capture works using the code from your Answer? I haven't tried it out just yet. And yes, debugging/understanding `motion` might be a different question. FYI Thanks for all your help! – FullMetalScientist Feb 14 '17 at 21:43
  • Except that canvas 2d context has to render only the first frame of an animated media inside an img tag. Won't work for streams. – Kaiido Feb 14 '17 at 23:26
  • @Kaiido OP is trying to capture a single image. Not sure what you mean? – guest271314 Feb 15 '17 at 03:30
  • @guest271314 **The goal is to get a picture of the video stream when I click** So since only the first frame of any animated media loaded inside an `` element is drawn by the `drawImage` method, he will get the first image of his stream, not the image currently displayed when he *clicks*. – Kaiido Feb 15 '17 at 03:34
  • @Kaiido Not sure what you mean by "animated". If `button` is clicked at `javascript` not only one image is rendered. – guest271314 Feb 15 '17 at 03:40
  • by animated I mean any animated media that the `` element does accept i.e [animated *GIF*](https://en.wikipedia.org/wiki/GIF#Animated_GIF), [*mjpeg*](https://en.wikipedia.org/wiki/Motion_JPEG), [*SMIL animated SVG*](https://en.wikipedia.org/wiki/SVG_animation). OP is talking about an mjpeg stream. [Specs are here](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts:canvasimagesource-3). [Dupe is here](http://stackoverflow.com/questions/36137686/stream-local-mjpg-video-to-html-canvas) – Kaiido Feb 15 '17 at 03:56
  • @Kaiido `motion` creates static `jpeg` images from a camera. OP is not describing a media stream or `mjpeg`, but the updated `src` of an `` element pointing to static image files. – guest271314 Feb 15 '17 at 04:04
  • "*video stream has URL `http://ip_address/stream`*" No, he is talking about an mjpeg stream, just like this one : http://37.58.136.166/axis-cgi/mjpg/video.cgi?resolution=704x576&dummy=1487131622311 And mjpeg format is not static jpeg... Only the first frame has all the data, following stream only sends what has changed between both frames. – Kaiido Feb 15 '17 at 04:12
  • @Kaiido You are perhaps misinterpreting requirement, or am doing so, here. From perspective here, requirement is to create a still image from `src` of another `img`, not stream to `canvas` element. – guest271314 Feb 15 '17 at 04:54