繁体   English   中英

使用AJAX在网页上动态预加载/显示网络摄像头快照

[英]Dynamically Preloading/Displaying Webcam Snapshots on a Web Page Using AJAX

我有一个IP摄像机,可将实时视频流式传输到我的网站。 问题是,它由ActiveX控件提供动力。 更糟糕的是,该控件是未签名的。 为了给使用IE以外的浏览器或(理所当然)不愿意更改其安全设置的人们提供更安全的替代方法,我使用了内置有640x480实时JPEG图像的快照脚本内置的摄像机。 计划是使用Javascript每隔500毫秒更新屏幕上实时显示的图像,而不必重新加载整个页面。

我尝试使用Image()对象预加载图像并在onload触发时更新图像元素的SRC属性:

function updateCam() {
  var url = "../snapshot.cgi?t=" + new Date().getTime();
  img = new Image();
  img.onload = function() {
    $("#livePhoto").attr("src", url);
    camTimer = setTimeout(updateCam, 500);
  }
  img.src = url;
}

这可以正常工作,但是很难确定何时禁用了相机,这是我需要做的,以使其正常降级。 在这种情况下,内部快照脚本被设置为返回HTTP状态代码204(无内容),当然,我没有办法使用Image对象检测到该错误。 此外,onload事件并非100%可靠。

因此,我正在使用jQuery(1.2.6版) ajax函数对URL进行GET请求,并在complete回调中评估状态代码并相应地设置URL:

function updateCam() {
  var url = "../snapshot.cgi?t=" + new Date().getTime();

  $.ajax({
    type: "GET",
    url: url,
    timeout: 2000,
    complete: function(xhr) {
      try {
        var src = (xhr.status == 200) ? url : '../i/cam-oos.jpg';
        $("#livePhoto").attr("src", src);            
      }
      catch(e) {
        JoshError.log(e);
      }

      camTimer = setTimeout(updateCam, 500);
    }
  });
}

这很漂亮。 但仅在IE中! 这是我想回答的问题:为什么在Firefox或Chrome中无法使用? complete事件甚至不会在Firefox中触发。 它确实可以在Chrome中启动,但是设置SRC很少真正加载请求的图像(通常不显示任何内容)。

发布第二个答案,因为第一个答案确实不正确。 我无法测试此解决方案(因为我无权访问您的网络摄像头脚本),但我建议您尝试清理来自摄像头的响应-由于您显然无法处理原始图像数据,请尝试添加dataFilter设置如下:

function updateCam() {
  var url = "../snapshopt.cgi?t=" + new Date().getTime();

  $.ajax({
    type: "GET",
    url: url,
    timeout: 2000,
    dataFilter : function(data, type) {
       return '<div></div>' //so it returns something...
    },
    complete: function(xhr) {
      try {
        var src = (xhr.status == 200) ? url : '../i/cam-oos.jpg';
        $("#live").attr("src", src);            
      }
      catch(e) {
        JoshError.log(e);
      }

      camTimer = setTimeout(updateCam, 500);
    }
  });
}

就像我说的那样,我一直无法测试-但是它可能允许jquery使用状态代码而不会像疯了一样崩溃。

img.onerror = function(){
    alert('offline');
}

好吧,我最终在非IE浏览器中使用了数据URI方案 (Eric Pascarello的技巧)。 我编写了一个HTTP处理程序(在VB.NET中)以代理IP摄像机,并以base-64编码图像:

Imports Common
Imports System.IO
Imports System.Net

Public Class LiveCam
    Implements IHttpHandler

    Private ReadOnly URL As String = "http://12.34.56.78/snapshot.cgi"
    Private ReadOnly FAIL As String = Common.MapPath("~/i/cam-oos.jpg")        

    Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
        Dim Data As Byte()

        With context.Response
           .ContentEncoding = Encoding.UTF8
           .ContentType = "text/plain"
           .Write("data:image/png;base64,")

           Try
               Using Client As New WebClient()
                   Data = Client.DownloadData(URL)
               End Using
           Catch ex As WebException
               Data = File.ReadAllBytes(FAIL)
           End Try

           .Write(Convert.ToBase64String(Data))
        End With
    End Sub
End Class

然后,我只是进行了一些非IE的检测(使用经典document.all检查),以便调用正确的URL /设置正确的SRC:

function updateCam() {
  var url = (document.all) ? "../snapshot.cgi?t=" : "../cam.axd?t=";

  url += new Date().getTime();

  $.ajax({
    type: "GET",
    url: url,
    timeout: 2000,
    complete: function(xhr) {
      try {
        var src;

        if(document.all)
          src = (xhr.status == 200) ? url : '../i/cam-oos.jpg';
        else
          src = xhr.responseText;

        $("#livePhoto").attr("src", src);            
      }
      catch(e) {
        JoshError.log(e);
      }

      camTimer = setTimeout(updateCam, 500);
    }
  });
}

不幸的是我不得不求助于这种解决方法。 我讨厌浏览器检测代码,并且讨厌服务器上的额外负载。 代理不仅会迫使我浪费更多的带宽,而且由于代理固有的缺陷以及基于base-64编码图像所需的时间,它也无法高效运行。 此外,它没有设置像IE 一样优雅地降级。 尽管我可以重新编写代理以使用HttpWebRequest并返回正确的状态代码,等等。我只是想找到最简单的方法,因为我讨厌处理此问题!

谢谢大家!

我相信jquery会尝试解释服务器的响应。 我相信某些浏览器更能容忍响应解释,因此,限制性更强的浏览器将失败,因为无法将图像视为HTML!

解决方案是使用HEAD请求类型而不是GET(类型:“ HEAD”)。 这样,您仍然可以获取状态响应,而无需获取图像本身。 因此,响应将为空(并且不应使您烦恼)。 同样,响应应该更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM