HTML img标记自动刷新浏览器导致图像撕裂

时间:2016-11-01 19:47:51

标签: javascript html linux http nginx

我基本上想在Linux上的网络浏览器中显示一个视频,通过我的USB网络摄像头在一个单独的进程中连续捕获到文件/tmp/ir.bmp,然后使用Javascript在我的网页中刷新该图像标签大约7赫兹(这是我的网络摄像头的捕获率)。我在Linux机器上使用Lua和OpenResty以及NGINX。

它实际上效果很好,大多数时候网页看起来像流畅的视频。但是,有些经常出现打嗝,在显示下一个图像之前,我会短暂地看到丢失图像的占位符消息。

我认为这与第二个进程写入的文件有关,并且同时尝试由NGINX读取。我该怎么做才能减轻这种影响并使视频流畅?谢谢。

<!DOCTYPE html>
<html>
<script>
setInterval("document.getElementById('img').src='ir.bmp?'+new Date().getMilliseconds()", 143);
</script>
<body>
<img id="img" src="ir.bmp" alt="My Video Stream" style="width:320px;height:240px;">
</body>
</html>

1 个答案:

答案 0 :(得分:1)

我想说你应该在服务器上使用某种视频编码器,然后使用HTML <video>标签提供。您将获得更好的带宽使用率。

然而,这个问题的范围有点过了。您可以通过简单地确保不显示损坏的图像来提高您已经完成的工作的质量。

您的代码存在一些问题:

  1. 您正在使用旧的基于字符串的setInterval版本(setInterval(&#34; ...&#34;)vs setInterval(function(){...});
  2. 您根本就在使用setInterval。您应该使用requestAnimationFrame来更新视图。我不会过分担心超出7fps的额外请求。
  3. 您没有处理错误案例。这可能是你得到一些坏帧的原因。
  4. 您正在使用Date.getMilliseconds,它返回当前第二个中的毫秒,这意味着只有1000个可能的值,这些值必须重复。我认为你把它与新的Date()混淆了.getTime()返回自纪元以来的毫秒数。
  5. 以下内容可能会更好,但仍有改进的余地(此代码未经测试)。以此为出发点。

    function loadNextImage(){
        // An image element for loading our next image
        var ourImage = new Image();
    
        // Setup the event handlers before setting the source
        ourImage.onload = function(){
            // Request the next frame
            requestAnimationFrame(loadNextImage);
    
            // Swap out the image element on the page with the new one
            var oldImage = document.getElementById('img');
            oldImage.parentElement.insertBefore(ourImage, oldImage);
            oldImage.parentElement.removeChild(oldImage);
        };
        ourImage.onerror = function(){
            // Something went wrong with this frame. Skip it and move on.
            requestAnimationFrame(loadNextImage);
        }
    
        // Finally load the image
        ourImage.src = "ir.bmp?" + new Date().getTime();
    };
    requestAnimationFrame(loadNextImage);
    

    此代码也可能存在一些问题,但它应该运行得更顺畅。祝你好运。