【发布时间】:2012-07-23 11:35:30
【问题描述】:
我使用以下 JavaScript 代码打开了一个网络摄像头:
const stream = await navigator.mediaDevices.getUserMedia({ /* ... */ });
是否有任何 JavaScript 代码可以停止或关闭网络摄像头?谢谢大家。
【问题讨论】:
标签: javascript html html5-video webrtc getusermedia
我使用以下 JavaScript 代码打开了一个网络摄像头:
const stream = await navigator.mediaDevices.getUserMedia({ /* ... */ });
是否有任何 JavaScript 代码可以停止或关闭网络摄像头?谢谢大家。
【问题讨论】:
标签: javascript html html5-video webrtc getusermedia
编辑
自从最初发布此答案以来,浏览器 API 已更改。
.stop() 在传递给回调的流上不再可用。
开发者必须访问构成流(音频或视频)的轨道并单独停止它们。
示例(来自上面的链接):
stream.getTracks().forEach(function(track) {
track.stop();
});
浏览器支持可能不同。
原答案
navigator.getUserMedia 在成功回调中为您提供了一个流,您可以在该流上调用.stop() 来停止录制(至少在 Chrome 中,似乎 FF 不喜欢它)
【讨论】:
stream.stop() 不适用于 chrome,mediaRecorder.stop() 停止录制,但它不会停止浏览器提供的流。你能看看这个stackoverflow.com/questions/34715357/…
使用以下任何功能:
// 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();
}
});
}
【讨论】:
stream.getTracks().forEach(track => { track.stop() })?或者,如果您确实经常这样做以证明简写的合理性,您始终可以定义一个辅助函数,如 stopAllTracks(stream)。
不要使用stream.stop(),它已被弃用
使用stream.getTracks().forEach(track => track.stop())
【讨论】:
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();
【讨论】:
假设我们在视频标签中有流式传输并且 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;
【讨论】:
使用不同的浏览器启动网络摄像头视频
对于 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="";
这样,网络摄像头的灯每次都会熄灭......
【讨论】:
试试下面的方法:
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();
【讨论】:
您可以使用成功处理程序中返回的流对象直接结束流到 getUserMedia。例如
localMediaStream.stop()
video.src="" 或 null 只会从视频标签中删除源。它不会释放硬件。
【讨论】:
由于您需要轨道来关闭流媒体,并且您需要 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();
});
当然,这会关闭所有活动的视频轨道。如果你有多个,你应该相应地选择。
【讨论】:
如果.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
您需要停止所有曲目(来自网络摄像头、麦克风):
localStream.getTracks().forEach(track => track.stop());
【讨论】:
启动网络摄像头
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();
【讨论】:
当通过 http 连接时,在流上使用 .stop() 可以在 chrome 上工作。使用 ssl (https) 时不起作用。
【讨论】:
请检查: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;
}
【讨论】:
以下代码对我有用:
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();
}
【讨论】:
有流形式successHandle的引用
var streamRef;
var handleVideo = function (stream) {
streamRef = stream;
}
//this will stop video and audio both track
streamRef.getTracks().map(function (val) {
val.stop();
});
【讨论】: