停止/关闭由navigator.getUserMedia打开的网络摄像头


Answers:


199

编辑

由于最初发布了此答案,因此浏览器API已更改。 .stop()在传递给回调的流上不再可用。开发人员将必须访问组成流(音频或视频)的轨道,并分别停止每个轨道。

此处了解更多信息:https : //developers.google.com/web/updates/2015/07/mediastream-deprecations?hl=zh-CN#stop-ended-and-active

示例(从上面的链接):

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

浏览器支持可能有所不同。

原始答案

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


2
我认为这stream.stop()不适用于chrome,mediaRecorder.stop()它会停止录制,而不会停止浏览器提供的数据流。你可以看看这个stackoverflow.com/questions/34715357/...
MUTHU

@Muntu,我认为这取决于我,stream.stop()正在运行(适用于Chrome)。因为我有一个webRTC流。因此,如果您在浏览器中进行录制,那么MediaRecorder.stop()会起作用吗?
Johan Hoeksma,

是的,但这引起了另一个问题。允许录制几秒钟/分钟后,应发生此停止录制的功能。您如何控制此操作:在默认的录制时间后将其停止?谢谢!
伊曼纽拉·柯尔塔

1
这将停止流,但是Chrome上的视频指示器仍保持活动状态,直到重新加载。有没有办法删除它呢?
Cyber​​supernova

@Cyber​​supernova您是否找到了解决方案?我认为页面刷新可能会起作用
samayo,

59

使用以下任何功能:

// 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();
        }
    });
}

注意:答案更新于:06/09/2020


2
谢谢你 mediaStream.stop已被弃用。
丹·布朗

@DanBrown您的解决方案是什么?
Webwoman

我强烈建议不要修改本机API的原型,以恢复已正式弃用并从浏览器中删除的功能。这是不规则的,以后可能会引起混乱。当您需要停止流中的所有轨道时,为什么不做stream.getTracks().forEach(track => { track.stop() })呢?或者,如果您确实经常进行此操作以证明简写的合理性,则可以始终定义一个辅助函数,例如stopAllTracks(stream)
卡伦

45

不使用stream.stop(),已弃用

MediaStream弃用

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


1
谢谢你这么多,,它的做工精细完全,由于折旧它混淆人们,哪一个是工作,但截至3月- 2019年上述溶液中铬做工精细..🙂
PANKAJ NAROLA

10

FF,Chrome和Opera现在已经开始getUserMedia通过公开曝光navigator.mediaDevices(可能会更改:)

在线演示

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();

9

使用其他浏览器启动网络摄像头视频

对于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="";

有了这个,网络摄像头灯每次都会熄灭...


10
这只会停止在<video>标签中显示视频,而不会停止摄像机。
G.Führ2015年

8

假设我们在video代码中流式传输,并且id是video- <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

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

localMediaStream.stop()

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


我懂了。我稍后再试。
周世恩

1
不是真的...在Firefox上不起作用。文档中提到并非在所有浏览器中都实现此方法……
Sdra 2014年

上述解决方案对我不起作用。做到了。
Scottmas

5

请尝试以下方法:

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();

4

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

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

1
for (let track of stream.getTracks()) { track.stop() }
guest271314

7
stream.getTracks().forEach(function (track) { track.stop() })在ES5中,这避免了冗长的babel变换for of
fregante

3

由于您需要轨道来关闭流式传输,并且需要通过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();
});

当然,这将关闭所有活动的视频轨道。如果有多个,则应进行相应选择。


2

您需要停止所有曲目(通过网络摄像头,麦克风):

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

0

通过http连接时,在流上使用.stop()在chrome上有效。使用ssl(https)时不起作用。


0

请检查以下内容: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;
}


0

以下代码为我工作:

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();
  }

0

启动和停止网络摄像头((更新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();

-1

对流形式成功有参考

var streamRef;

var handleVideo = function (stream) {
    streamRef = stream;
}

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

1
该答案与已经给出的其他答案基本相同。
Dan Dascalescu

@DanDascalescu不能远射。看到,在这个例子中,他清楚地证明了自己调用地图功能的能力。
charliebeckwith19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.