我基本上想在 Linux 上的网络浏览器中显示视频,方法是在一个单独的进程中从我的 USB 网络摄像头不断捕获到文件/tmp/ir.bmp,然后使用 Javascript 在我的网页中刷新该图像标签大约 7 Hz(这是我的网络摄像头的捕获率)。我在 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>
最佳答案
我会说你应该在服务器上使用某种视频编码器,然后使用 HTML <video>
提供它标签。您将获得更好的带宽使用率。
但是,这有点超出了这个问题的范围。只需确保不显示损坏的图像,您就可以提高现有工作的质量。
您的代码存在一些问题:
- 您使用的是旧的基于字符串的 setInterval 版本(setInterval("...") 与 setInterval(function(){ ... });
- 您正在使用 setInterval。你真的应该使用 requestAnimationFrame 来更新 View 。我不会太担心提出超过 7fps 的额外要求。
- 您没有处理错误情况。这可能就是您得到一些糟糕帧的原因。
- 您使用的是 Date.getMilliseconds,它返回当前秒中的毫秒数,这意味着只有 1000 个可能的值,这些值肯定会重复。我认为您将它与返回自纪元以来的毫秒数的 new Date().getTime() 混淆了。
下面的可能会更好,但肯定还有改进的余地(并且此代码未经测试)。以此为起点。
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);
此代码也可能存在一些问题,但它应该运行得更流畅。祝你好运。
关于javascript - HTML img标签自动刷新浏览器导致图片撕裂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40367548/