开发者

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:

  1. <img src=""/> <--- how can I load an image url that is located within the javascript code

  2. within 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() and setInterval()

  • 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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜