admin管理员组文章数量:1435859
I am trying to write a live stream of a mjpg video to an html canvas.
The following: / has a list of public webcams with mjpeg videos but they seem to be writing < frameset > tags with frame elements and I can't pick up how its working in a fiddle.
The ideal solution has any live mjpg (ideally a link?) streaming on an html canvas in fiddle.
Any helpful resources are appreciated, I would like to do this without including external libraries (jquery allowed)
Edit: Related: How to make an snapshot from a MJPEG stream in HTML
Edit: I too have a local mjpg to draw from like the example. Solution can use local stream
I am trying to write a live stream of a mjpg video to an html canvas.
The following: http://camelive.info/ has a list of public webcams with mjpeg videos but they seem to be writing < frameset > tags with frame elements and I can't pick up how its working in a fiddle.
The ideal solution has any live mjpg (ideally a link?) streaming on an html canvas in fiddle.
Any helpful resources are appreciated, I would like to do this without including external libraries (jquery allowed)
Edit: Related: How to make an snapshot from a MJPEG stream in HTML
Edit: I too have a local mjpg to draw from like the example. Solution can use local stream
Share Improve this question edited May 23, 2017 at 12:16 CommunityBot 11 silver badge asked Mar 21, 2016 at 17:19 mattydmattyd 1,6832 gold badges17 silver badges26 bronze badges 4- Not sure if this helps, but you must have check this example – Bhavik Commented Mar 21, 2016 at 17:23
- Looking at it now, i think this is the right idea. Ill try and get preliminary fiddle attached momentarily – mattyd Commented Mar 21, 2016 at 17:29
- Per specs you can't. Some buggy browsers like chrome will let you do it, but it's a bug. Canvas drawImage draws only the first frame of an animated ´img´. – Kaiido Commented Mar 21, 2016 at 23:41
- Yeah, what I ended up doing is update image src a new image with a appended date string (browser caching), then re-render canvas – mattyd Commented Mar 21, 2016 at 23:47
2 Answers
Reset to default 2According to specs about the CanvasRenderingContext2D drawImage
method,
Specifically, when a CanvasImageSource object represents an animated image in an HTMLImageElement, the user agent must use the default image of the animation (the one that the format defines is to be used when animation is not supported or is disabled), or, if there is no such image, the first frame of the animation, when rendering the image for CanvasRenderingContext2D APIs.
This applies to .gif, SMIL animated .svg and .mjpeg media. So once you fetched the data, only one frame should be drawn onto the canvas.
Note that chrome has a bug and only respect it for .gif images, but they may fix it someday.
One solution as you noticed yourself, is to fetch an other fresh frame, with the clear-cache hack ('your.url/?' + new Date().getTime();
) but you will loose any advantages of the mjpeg format (partial frame content) and can't be sure when the refreshing will happen.
So a better solution if applicable, would be to use a video format. Each frame of a video can be drawn to the canvas.
Edit 2018
A third solution came to my little mind two years later:
UAs are not tied to keep in memory the same default image for all 2DContexts in the document.
While for others format we are still kinda stuck, for MJPEG streams, which don't have a well defined default image, we actually fall to the first frame of the animation.
So by drawing the <img>
containing our MJPEG stream on two different canvases, at different times, we can theoretically have two different frames of our same MJPEG stream to be drawn on the canvases.
Here is a proof of concept only tested on Firefox 62.
var ctx_stream = stream.getContext('2d');
var ctx_direct = direct.getContext('2d');
img.onload = function() {
stream.width = direct.width = this.naturalWidth;
stream.height = direct.height = this.naturalHeight;
// onload should fire multiple times
// but it seems it's not at every frames
// so we'll disable t and use an interval instead
this.onload = null;
setInterval(draw, 500);
};
function draw() {
// create a *new* 2DContext
var ctx_off = stream.cloneNode().getContext('2d');
ctx_off.drawImage(img, 0,0);
// and draw it back to our visible one
ctx_stream.drawImage(ctx_off.canvas, 0,0);
// draw the img directly on 'direct'
ctx_direct.drawImage(img, 0,0);
}
img.src = "http://webcam.st-malo./axis-cgi/mjpg/video.cgi?resolution=704x576&dummy=1491717369754";
canvas,img{
max-height: 75vh;
}
Using a new offcreen canvas every frame: <br><canvas id="stream"></canvas><br>
The original image: <br><img id="img"><br>
Drawing directly the <img> (if this works your browser doesn't follow the specs): <br><canvas id="direct"></canvas><br>
So while this solution will obviously e with a performance impact (we are creating a whole new canvas element and its 2DContext every frame), it's still probably better than flooding the network. And all this should be Garbage Collected quite easily anyway.
Many of the IP mjpeg camera that are out there actually send individual jpeg files at a predefined frame rate, which when updated frequently, seems like a video.
You need to check your camera's manufacturers API for the correct url to use to get the image stream, for example with a Foscam camera I've done the following before and it works perfectly:
<img id='videostream' src="http://123.456.789.233:8080/videostream.cgi">
You obviously will have to get the correct IP and port number of the camera (if exists).
UPDATE - This does not mean you can not have other live video stream methods available, it is only the simplest way I know to do get live video from an IP camera.
UPDATE 2 - also some cameras have username & password so you'll probably have to append those to the url videostream.cgi?user=your_user&password=your_password
Hope this helps.
本文标签: javascriptStream local mjpg video to html canvasStack Overflow
版权声明:本文标题:javascript - Stream local mjpg video to html canvas - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745675292a2669814.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论