6

我如何在纯 js 中停止和退出,在 WEBRTC api js 中流式传输网络摄像头,我的代码中有以下脚本:

<script type="text/javascript">
$(document).ready(function() {
    $("#abrirModal").click(function() {
        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
        var constraints = {
            audio: false,
            video: true
        };
        var live = document.getElementById("live");

        function successCallback(stream) {
            window.stream = stream; // stream available to console
            if (window.URL) {
                live.src = window.URL.createObjectURL(stream);
            } else {
                live.src = stream;
            }
            $("#myModal").modal("show");
            window.setTimeout(function() {
                $("#myModal").modal("hide");
            }, 9000);
        }

        function errorCallback(error) {
            console.log("navigator.getUserMedia error: ", error);
        }

     navigator.getUserMedia(constraints, successCallback, errorCallback);
    });
});
 </script>

如何在其他 file.js 中关闭和退出网络摄像头,例如:

  function exitWebCam () {  
     document.getElementById("live")."close the web cam";
  }
4

2 回答 2

9

您通过关闭其所有轨道来结束流: stream.getTracks().forEach(function(track) { track.stop(); })

于 2016-10-23T18:00:02.787 回答
6

菲利普怎么说。还要清除对流的所有引用,以便释放它。这里有一个错误:

live.src = stream;

错误的(src需要一个 URL,而不是一个流)。幸运的是,它从未运行过,因为它window.URL存在于所有执行 WebRTC 的浏览器中。但createObjectURL会导致相机保持开启状态。而是这样做:

if (typeof live.srcObject == "object") {
    live.srcObject = stream;
} else {
    live.src = window.URL.createObjectURL(stream)
}

或者就像live.srcObject = stream现在srcObject在所有 WebRTC 浏览器中实现的那样(Chrome 54+)。它正确处理资源,因此当您稍后执行时,浏览器知道它可以垃圾收集流(如果您错过了对任何轨道的live.srcObject = null调用,则关闭相机)。track.stop()

createObjectURL很糟糕且已弃用,除非您记得revokeObjectURL. 这就是为什么您的相机永远不会自行停止的原因,以防您想知道,所以如果您在代码中看到这种模式,请帮忙将其删除。

比较

试试这些进行比较。视频会在 2 秒后消失,但请留意相机指示灯和浏览器内的录制指示灯。首先是srcObject(Chrome的https 小提琴):

(在 Firefox 中,摄像头指示灯和指示灯应在约 10 秒后熄灭;在 Chrome 中约 20 秒。)

var wait = ms => new Promise(resolve => setTimeout(resolve, ms));

navigator.mediaDevices.getUserMedia({video: true})
  .then(stream => video.srcObject = stream)
  .then(() => wait(2000))
  .then(() => video.srcObject = null)
  .catch(e => console.log(e.name + ": "+ e.message));
<video id="video" width="160" height="120" autoplay></video>

然后使用createObjectURL(不使用revokeObjectURL)(Chrome 的https 小提琴):

(在两种浏览器中永远保持打开状态。)

var wait = ms => new Promise(resolve => setTimeout(resolve, ms));

navigator.mediaDevices.getUserMedia({video: true})
  .then(stream => video.src = URL.createObjectURL(stream))
  .then(() => wait(2000))
  .then(() => video.srcObject = null)
  .catch(e => console.log(e.name + ": "+ e.message));
<video id="video" width="160" height="120" autoplay></video>

track.stop()显式调用会停止它,但前提是你已经停止了所有轨道,这比听起来更容易,因为现在可以克隆轨道。所以避免createObjectURL

于 2016-10-24T02:49:18.373 回答