webcam image refresh with ajax
I have an image that is being constantly updated from a local webcam source, it is then displayed on a website. I can get the image to show and by refreshing the page the image will update (obviously).
What I am wondering is, how can I update this image every (lets say) 5 seconds, without having to refresh the page manually (ie. utilizing ajax).
Basic things I am not too sure about:
<img src=""/>
<--- how can I load an image url that is located within the javascript codewithin the javascript code, how can I create a function that will automatically update the image source, without having to reload the page
As I understand it, upon readin开发者_C百科g around, one of the main problems is that browsers will load the cached image unless the resulting httprequest looks different each time, as such am I required to add an additional item within the url string (ie. www.yoursire.com?image=foo&date=bar (the date is grabbed by date function or some other iterated value)) in order to circumvent this horrible browser predisposition?
Thanks in advance!
Without writing all the code
look at the javascript functions
setTimeout()
andsetInterval()
it's easy to change the src attribute of ana element
document.getElementbyId("imageId").setAttribute("src", imageUrl);
if your image request url is the same everytime (but the pic has changed server-side) you can either add a "no-cache" to the ajax request header, or possibly add a random query string to the image to force a reload each time (e.g http://mydomain/myimage?3754854 )
With jQuery:
$(document).ready(function() {
window.setInterval("refreshCamera();", 1000); // one second interval
});
var url = 'http://www.x.com/abc?refresh=';
var forcerefresh = 0;
function refreshCamera()
{
forcerefresh = forcerefresh + 1;
$('#myImageId').attr('src',url + forcerefresh);
}
(the force refresh thing is to prevent browser from using locally cached image)
I have done this and it works using setting the image source. Also on the server-side, you have to send no-cache HTTP headers to prevent caching.
<img src="" id="webcam" />
<script type="text/javascript">
var int=self.setInterval("reload()",1000);
function reload(){
$("#webcam").attr("src", "/mysite/webcamImage");
}
</script>
You could use jquery to load an image object and then attach a timer and run the code for every 5 seconds.
Here's an example:
// when the DOM is ready
$(function () {
var img = new Image();
// wrap our new image in jQuery, then:
$(img)
// once the image has loaded, execute this code
.load(function () {
// set the image hidden by default
$(this).hide();
// with the holding div #loader, apply:
$('#loader')
// remove the loading class (so no background spinner),
.removeClass('loading')
// then insert our image
.append(this);
// fade our image in to create a nice effect
$(this).fadeIn();
})
// if there was an error loading the image, react accordingly
.error(function () {
// notify the user that the image could not be loaded
})
// *finally*, set the src attribute of the new image to our image
.attr('src', 'images/headshot.jpg');
});
Read more about this here:
- http://jqueryfordesigners.com/image-loading/
About preventing the caching of dynamically loaded images you can just add the last modified timestamp in the url:
<img src="image.jpg?lastmodified=1291235678" ...
I had the same need, so I'm appending my own js solution below. Occasionally our webcam will be in the middle of writing the jpg to a directory when the ajax refresh occurs, so instead of displaying a broken image, I'm presenting an animated gif.
JS:
<script>
$(document).ready(function () {
(function () {
// show webcam jpg on initial page load
var refreshWebcam = function () {
// webcam link is appended with a timestamp to prevent caching
var webcamImg = 'http://abs_path_to_webcam_img/webcam1.jpg' + '?' + (new Date()).getTime();
var loadingImg = 'http://abs_path_to_webcam_loading_img.gif'
$.ajax({
url: webcamImg,
type: 'HEAD',
error: function () {
$('#refresh').attr('src', loadingImg);
//console.log('failed loading ' + webcamImg);
// if there's an error, retry loading image every half second
setTimeout(function () {
refreshWebcam();
}, 500)
},
success: function () {
$('#refresh').attr('src', webcamImg);
//console.log('successfully loaded ' + webcamImg);
}
});
};
// refresh webcam jpg every 5 seconds
window.setInterval(refreshWebcam, 5000);
refreshWebcam();
})();
});
HTML
<img alt="Web Camera Image" id="refresh" src="http://abs_path_to_webcam_loading_img.gif" />
Disabling caching will overwhelm your webcam (even good ones) if it gets popular
I tried allowing the image to be allowed to be cached for 6 seconds (Cache-Control: max-age=6), because I needed to prevent a webcam from being overwhelmed. The code that I was working with looked a bit like this, but it has a problem:
<img alt="Webcam image of something popular" id="liveimage" src="http://example.com/webcams/suddenlypopular.jpg" /><br />
<script type="text/javascript">
(function() {
setInterval(function() {
var myImageElement = document.getElementById('liveimage');
myImageElement.src = 'http://example.com/webcams/suddenlypopular.jpg';
}, 6000);
}());
</script>
Previously, the web-developer had put a ?rand=(random-number) in as a cache-busting technique. That's bad when the image is cacheble (even if only for a short period of time), because if means that you may (depending on whether your cache will consider query parameters as non-cachable), mean you get a very poor cache hit rate and you get a lot of page representations being built up.
The problem was that the image was now not refreshing, because although the src attribute was being reassigned, it wasn't actually changing to a different value, so the browser (Chrome 51) wasn't updating the image. I changed the logic to have either an ?1
or a ?2
query string argument, and alternate between them.
<img alt="Webcam image of something popular" id="liveimage" src="http://example.com/webcams/suddenlypopular.jpg?1" /><br />
<script type="text/javascript">
(function() {
setInterval(function() {
var myImageElement = document.getElementById('liveimage');
if (myImageElement.src == 'http://example.com/webcams/suddenlypopular.jpg?1') {
myImageElement.src = 'http://example.com/webcams/suddenlypopular.jpg?2';
} else {
myImageElement.src = 'http://example.com/webcams/suddenlypopular.jpg?1';
}
myLogElement.innerHTML = myImageElement.src;
}, 6000);
}());
</script>
EDIT: While this works in Chrome and IE, it didn't work in Firefox, so I came up with an alternative solution that is working in Chrome, Firefox and IE (Safari is currently untested).
<img alt="Webcam image of something popular" id="liveimage" src="http://example.com/webcams/suddenlypopular.jpg" />
<script type="text/javascript">
(function() {
setInterval(function() {
var myImageElement = document.getElementById('liveimage');
var d = new Date();
// 6000 is 6 seconds; the desired refresh rate
// % n is a bit of an experiment for being nice on cache invalidation; it also puts a bound on how out-of-date something would be regarding clock skew.
var timeSlice = Math.floor(d.getTime() / 6000) % 3;
myImageElement.src = 'http://example.com/webcams/suddenlypopular.jpg?t=' + timeSlice;
}, 6000);
}());
</script>
So now I have a cache-friendly webcam that does update.
Apache reverse-proxy configuration
Here's a snippet from Apache httpd for how you might reverse-proxy a webcam to set a particular caching policy.
<Location /webcams/suddenlypopular.jpg>
ProxyPass http://mywebcamdevice.example.com/snapshot.jpg
ProxyPassReverse http://mywebcamdevice.example.com/snapshot.jpg
ExpiresByType image/jpeg "access plus 6 seconds"
Header unset ETag
Header unset Last-Modified
</Location>
精彩评论