【问题标题】:Stop/Close webcam stream which is opened by navigator.mediaDevices.getUserMedia [closed]停止/关闭由 navigator.mediaDevices.getUserMedia 打开的网络摄像头流 [关闭]
【发布时间】:2012-07-23 11:35:30
【问题描述】:

我使用以下 JavaScript 代码打开了一个网络摄像头:

const stream = await navigator.mediaDevices.getUserMedia({ /* ... */ });

是否有任何 JavaScript 代码可以停止或关闭网络摄像头?谢谢大家。

【问题讨论】:

    标签: javascript html html5-video webrtc getusermedia


    【解决方案1】:

    编辑

    自从最初发布此答案以来,浏览器 API 已更改。 .stop() 在传递给回调的流上不再可用。 开发者必须访问构成流(音频或视频)的轨道并单独停止它们。

    更多信息在这里:https://developers.google.com/web/updates/2015/07/mediastream-deprecations?hl=en#stop-ended-and-active

    示例(来自上面的链接):

    stream.getTracks().forEach(function(track) {
      track.stop();
    });

    浏览器支持可能不同。

    原答案

    navigator.getUserMedia 在成功回调中为您提供了一个流,您可以在该流上调用.stop() 来停止录制(至少在 Chrome 中,似乎 FF 不喜欢它)

    【讨论】:

    • 我认为 stream.stop() 不适用于 chrome,mediaRecorder.stop() 停止录制,但它不会停止浏览器提供的流。你能看看这个stackoverflow.com/questions/34715357/…
    • @Muntu,我认为这取决于,对我来说 stream.stop() 正在工作(在 chrome 中)。因为我有一个 webRTC 流。那么如果你在浏览器中录制 mediaRecorder.stop() 会起作用吗?
    • 是的,但这引发了另一个问题。这个停止记录的功能应该在允许记录几秒/分钟后出现。您如何控制它:在默认录制时间后停止它?谢谢!
    • 这会停止流,但 chrome 上的视频指示器仍然保持活动状态,直到重新加载。有没有办法把它也去掉?
    • @Cyber​​supernova 你找到解决方案了吗?我认为页面刷新可能会起作用
    【解决方案2】:

    使用以下任何功能:

    // stop both mic and camera
    function stopBothVideoAndAudio(stream) {
        stream.getTracks().forEach(function(track) {
            if (track.readyState == 'live') {
                track.stop();
            }
        });
    }
    
    // stop only camera
    function stopVideoOnly(stream) {
        stream.getTracks().forEach(function(track) {
            if (track.readyState == 'live' && track.kind === 'video') {
                track.stop();
            }
        });
    }
    
    // stop only mic
    function stopAudioOnly(stream) {
        stream.getTracks().forEach(function(track) {
            if (track.readyState == 'live' && track.kind === 'audio') {
                track.stop();
            }
        });
    }
    

    【讨论】:

    • 谢谢。 mediaStream.stop 已被弃用。
    • @DanBrown 你的解决方案是什么?
    • 我强烈反对修改原生 API 的原型以恢复已被正式弃用并从浏览器中删除的功能。这是不规则的,以后可能会引起混乱。当您需要停止流中的所有曲目时,为什么不直接使用stream.getTracks().forEach(track => { track.stop() })?或者,如果您确实经常这样做以证明简写的合理性,您始终可以定义一个辅助函数,如 stopAllTracks(stream)
    【解决方案3】:

    不要使用stream.stop(),它已被弃用

    MediaStream Deprecations

    使用stream.getTracks().forEach(track => track.stop())

    【讨论】:

    • 非常感谢,它工作得很好,由于折旧,它让人们感到困惑的是哪个工作,但截至 2019 年 3 月,上述解决方案在 chrome 中工作正常.. ?跨度>
    • 如何恢复赛道?
    • @NeerajJain 一旦你关闭了 mediaStreamTrack 它就不能退出结束状态
    【解决方案4】:

    FF、Chrome 和 Opera 现已开始将 getUserMedia 通过 navigator.mediaDevices 公开为标准(可能会更改:)

    online demo

    navigator.mediaDevices.getUserMedia({audio:true,video:true})
        .then(stream => {
            window.localStream = stream;
        })
        .catch( (err) =>{
            console.log(err);
        });
    // later you can do below
    // stop both video and audio
    localStream.getTracks().forEach( (track) => {
    track.stop();
    });
    // stop only audio
    localStream.getAudioTracks()[0].stop();
    // stop only video
    localStream.getVideoTracks()[0].stop();
    

    【讨论】:

      【解决方案5】:

      假设我们在视频标签中有流式传输并且 id 是视频 - <video id="video"></video> 那么我们应该有以下代码 -

      var videoEl = document.getElementById('video');
      // now get the steam 
      stream = videoEl.srcObject;
      // now get all tracks
      tracks = stream.getTracks();
      // now close each track by having forEach loop
      tracks.forEach(function(track) {
         // stopping every track
         track.stop();
      });
      // assign null to srcObject of video
      videoEl.srcObject = null;
      

      【讨论】:

        【解决方案6】:

        使用不同的浏览器启动网络摄像头视频

        对于 Opera 12

        window.navigator.getUserMedia(param, function(stream) {
                                    video.src =window.URL.createObjectURL(stream);
                                }, videoError );
        

        对于 Firefox Nightly 18.0

        window.navigator.mozGetUserMedia(param, function(stream) {
                                    video.mozSrcObject = stream;
                                }, videoError );
        

        对于 Chrome 22

        window.navigator.webkitGetUserMedia(param, function(stream) {
                                    video.src =window.webkitURL.createObjectURL(stream);
                                },  videoError );
        

        使用不同的浏览器停止网络摄像头视频

        对于 Opera 12

        video.pause();
        video.src=null;
        

        对于 Firefox Nightly 18.0

        video.pause();
        video.mozSrcObject=null;
        

        对于 Chrome 22

        video.pause();
        video.src="";
        

        这样,网络摄像头的灯每次都会熄灭......

        【讨论】:

        • 这只会停止显示
        【解决方案7】:

        试试下面的方法:

        var mediaStream = null;
            navigator.getUserMedia(
                {
                    audio: true,
                    video: true
                },
                function (stream) {
                    mediaStream = stream;
                    mediaStream.stop = function () {
                        this.getAudioTracks().forEach(function (track) {
                            track.stop();
                        });
                        this.getVideoTracks().forEach(function (track) { //in case... :)
                            track.stop();
                        });
                    };
                    /*
                     * Rest of your code.....
                     * */
                });
        
            /*
            * somewhere insdie your code you call
            * */
            mediaStream.stop();
        

        【讨论】:

          【解决方案8】:

          您可以使用成功处理程序中返回的流对象直接结束流到 getUserMedia。例如

          localMediaStream.stop()
          

          video.src=""null 只会从视频标签中删除源。它不会释放硬件。

          【讨论】:

          • 我明白了。我稍后会尝试。
          • 不是真的... 在 firefox 上不起作用。文档提到此方法并非在所有浏览器中都实现...
          • 上述解决方案对我不起作用。这样做了。
          【解决方案9】:

          由于您需要轨道来关闭流媒体,并且您需要 stream 对象才能到达轨道,所以我在上面 Muaz Khan 的回答的帮助下使用的代码如下:

          if (navigator.getUserMedia) {
              navigator.getUserMedia(constraints, function (stream) {
                  videoEl.src = stream;
                  videoEl.play();
                  document.getElementById('close').addEventListener('click', function () {
                      stopStream(stream);
                  });
              }, errBack);
          
          function stopStream(stream) {
          console.log('stop called');
          stream.getVideoTracks().forEach(function (track) {
              track.stop();
          });
          

          当然,这会关闭所有活动的视频轨道。如果你有多个,你应该相应地选择。

          【讨论】:

            【解决方案10】:

            如果.stop() 已被弃用,那么我认为我们不应该像@MuazKhan 那样重新添加它。这是为什么事物被弃用并且不应再使用的原因。只需创建一个辅助函数......这是一个更多的 es6 版本

            function stopStream (stream) {
                for (let track of stream.getTracks()) { 
                    track.stop()
                }
            }
            

            【讨论】:

            • for (let track of stream.getTracks()) { track.stop() }
            • stream.getTracks().forEach(function (track) { track.stop() }) 在 ES5 中,这避免了 lengthy babel transforms of for of
            【解决方案11】:

            您需要停止所有曲目(来自网络摄像头、麦克风):

            localStream.getTracks().forEach(track => track.stop());
            

            【讨论】:

              【解决方案12】:

              启动和停止网络摄像头,(更新 2020 React es6)

              启动网络摄像头

              stopWebCamera =()=>
              
                     //Start Web Came
                    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                      //use WebCam
                      navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
                        this.localStream = stream;
                        this.video.srcObject = stream;
                        this.video.play();
                      });
                    }
               }
              

              一般停止网络摄像头或视频播放

              stopVideo =()=>
              {
                      this.video.pause();
                      this.video.src = "";
                      this.video.srcObject = null;
              
                       // As per new API stop all streams
                      if (this.localStream)
                        this.localStream.getTracks().forEach(track => track.stop());
              }
              

              停止网络摄像头功能甚至适用于视频流:

                this.video.src = this.state.videoToTest;
                this.video.play();
              

              【讨论】:

              • 是否可以在不让用户再次选择窗口的情况下停止然后重新启动截屏共享?
              【解决方案13】:

              当通过 http 连接时,在流上使用 .stop() 可以在 chrome 上工作。使用 ssl (https) 时不起作用。

              【讨论】:

                【解决方案14】:

                请检查:https://jsfiddle.net/wazb1jks/3/

                navigator.getUserMedia(mediaConstraints, function(stream) {
                    window.streamReference = stream;
                }, onMediaError);

                停止录制

                function stopStream() {
                    if (!window.streamReference) return;
                
                    window.streamReference.getAudioTracks().forEach(function(track) {
                        track.stop();
                    });
                
                    window.streamReference.getVideoTracks().forEach(function(track) {
                        track.stop();
                    });
                
                    window.streamReference = null;
                }

                【讨论】:

                  【解决方案15】:

                  以下代码对我有用:

                  public vidOff() {
                  
                        let stream = this.video.nativeElement.srcObject;
                        let tracks = stream.getTracks();
                  
                        tracks.forEach(function (track) {
                            track.stop();
                        });
                  
                        this.video.nativeElement.srcObject = null;
                        this.video.nativeElement.stop();
                    }
                  

                  【讨论】:

                    【解决方案16】:

                    有流形式successHandle的引用

                    var streamRef;
                    
                    var handleVideo = function (stream) {
                        streamRef = stream;
                    }
                    
                    //this will stop video and audio both track
                    streamRef.getTracks().map(function (val) {
                        val.stop();
                    });
                    

                    【讨论】:

                    • 这个答案与已经给出的其他几个答案基本相同。
                    • 绝对不是@DanDascalescu。看,在这个例子中,他清楚地展示了他回忆地图功能的能力。
                    猜你喜欢
                    • 1970-01-01
                    • 2017-01-29
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多