在不刷新页面的情况下停止getUserMedia的网络摄像头流[重复]

Posted

技术标签:

【中文标题】在不刷新页面的情况下停止getUserMedia的网络摄像头流[重复]【英文标题】:stop the webcam streaming of getUserMedia without page refreshing [duplicate] 【发布时间】:2013-04-02 05:52:39 【问题描述】:

我正在尝试使用 javascript 函数关闭网络摄像头(必须在收到一些 Ajax 响应后将其关闭),但如果不刷新页面似乎无法关闭。关闭它的所有方法,如 video.src = null、video.pause...等,在任何浏览器中都不起作用。唯一的方法是关闭作为参数传递到成功函数上的流,那么有什么方法可以在函数成功之外使用这个对象来关闭网络摄像头?

我知道之前有人问过这个问题(Stop/Close webcam using getUserMedia and RTCPeerConnection Chrome 25),但是我的需求不同,所以我需要一些帮助来解决这个问题

谢谢!

编辑:我的工作代码试图关闭网络摄像头:

navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia ||  navigator.webkitGetUserMedia || navigator.msGetUserMedia;
if(navigator.getUserMedia)
  var video_constraints = 
    mandatory: 
       maxHeight: 480,
       maxWidth: 640 
    ,
    optional: []
  ;
  var self = this;
  self.navigator.getUserMedia(
      audio: false,
      video: video_constraints
  , self.onSuccess, onError);

else
  alert('An error has occurred starting the webcam stream, please revise the instructions to fix the problem');


function onSuccess(stream) 
  var video = document.getElementById('webcam');

  if(navigator.webkitGetUserMedia || navigator.mozGetUserMedia)
      video.src = window.URL.createObjectURL(stream);
  
  else if(navigator.msGetUserMedia)
      //future implementation over internet explorer
  
  else
      video.src = stream;
  
  self.localStream = stream;
  video.play();

function onError() 
  alert('There has been a problem retrieving the streams - did you allow access?');


function closeWebcamConnection()
  this.localStream.stop();

uff..在这里贴代码真的很复杂XD

【问题讨论】:

【参考方案1】:

像 asgoth 建议的那样保存对 LocalMediaStream 的引用是正确的,但在 Chrome 47 中对我来说。localStream.stop(); 给了我一个错误:

未捕获的类型错误:localStream.stop 不是函数

我通过调用:

localStream.getVideoTracks()[0].stop();

【讨论】:

目前(截至 2015 年 12 月)这是一个重要的答案。我们在一个网络应用程序中遇到了这个问题,导致 Chrome 中的选项卡崩溃并显示“Aw, snap”消息。这为我们解决了问题。 这与 TokBox / OpenTok 错误_webRTCStream.stop() is not a function有关。 仍然不会停止使用这种方法。甚至还有一个 removeTrack 功能,您可以使用它来删除所有曲目,但我的网络摄像头灯仍然亮着。 是的,这个今天真的很有效.. 我将答案扩展了一点,并使用以下方法成功关闭了所有轨道,包括音频:localStream.getTracks().forEach(track => track.stop());【参考方案2】:

您需要通过执行stop() 方法来停止LocalMediaStream 对象。我有类似的问题。你需要做的是:

getUserMedia()执行的onSuccess回调函数中保留对LocalMediaStream的引用:

var localStream;

onUserMediaSuccess = function(stream) 
   // attach to a video element
   ...
   // keep a reference
   localStream = stream;
;

在需要的地方停止 LocalMediaStream:

localStream.stop(); 

更多信息在我自己的question(和answer)中。

【讨论】:

嗯,好吧,我尝试在我的代码中添加类似的内容,但我不知道如何,因为您的代码完全不同。我也看到了你的老问题,但对我来说仍然更难理解。如果您使用“this”来停止流,为什么要将流对象保存在“self”对象中?我将在这里发布我的代码,因此您可以告诉我如何实现您的解决方案: 我承认在没有整个上下文的情况下使用“self”可能会造成混淆。我已经调整了我的答案。只需将引用保存在全局或范围变量 localStream 中即可。 难以置信!我刚刚在 Chrome 和 Firefox 中进行了测试,并且..它完美地工作!!现在我记得了,前一次我也尝试过相同的东西,但没有奏效。现在,如果我可以在不使用繁琐的 ajax 的情况下将画布图像捕获作为请求发送,那将是完美的,但这是另一个主题 jej。谢谢你很配!独特之处在于:我可以将它与 HTTPS 一起使用吗? 不再工作了:developer.mozilla.org/en-US/docs/Web/API/MediaStream【参考方案3】:

除了asgoth's answer

localStream.stop() 在 Chrome 45 中被弃用,在 Chrome 47 中被移除

如果你从多个地方调用 .stop(),你可以使用下面的帮助器作为 stop 函数来将逻辑保持在一个地方。

var localStream;

onUserMediaSuccess = function(stream) 

  // re-add the stop function
  if(!stream.stop && stream.getTracks) 
    stream.stop = function()         
      this.getTracks().forEach(function (track) 
         track.stop();
      );
    ;
  

  // attach to a video element
  ...
  // keep a reference
  localStream = stream;
;

【讨论】:

【参考方案4】:

这似乎是 Chrome 中的一个错误区域,并且行为不断变化。 仅当您通过 http(不是 https)连接时,这似乎才有效:

var myStream;
function successCallback( stream ) 
    ...
    myStream = stream; // used to close the stream later


function closeStream()
   myStream.stop(); 
   myStream = null;

由于某些奇怪的原因,这在 SSL (https) 上不起作用(在 Chrome for Linux,Ver 27 Dev 上检查)

【讨论】:

对不起,你的方法对我不起作用。我想我前段时间看到过类似的东西,但也没有用。我已经尝试过最新版本的 Chrome 和 Firefox。此外,我需要使用 HTTPS 来实现。 我只在 Linux 上的 Chrome 27 dev 上测试过它。你的设置是什么?如果您需要 HTTPS(就像我一样),无论如何它都不适合您。我在 WebRTC 问题跟踪器上打开了一个问题。 link 哦该死的XD!我的应用程序必须通过 HTTPS 运行。我使用的是 Windows 7 64 位企业版。我的 Web 应用程序在面向 Web 开发人员的 Eclipse Java EE IDE 版本 Indigo Service Release 2 中运行。我已经在 Firefox 19.0.2 和 Chrome 26.0.1410.43 上进行了测试。它也适用于 Opera 12.15.. 嗯,如果我可以使用 servlet 中的 request.getParameter 函数来获取 dataURL 格式的画布图像,那对我来说不是问题。我还没有找到方法,可能是不可能的。你尝试过类似的方法吗? 经过额外的测试,只要你的实现简单并且不涉及顺序使用getUserMedia的多个窗口,它应该可以使用HTTPS。 好的,感谢您的帮助。无论如何,当我通过 servlet 刷新页面时,我已经停止了。通过请求而不是使用 ajax 发送捕获的画布很容易。事实上,这是管理会话的更好方法。【参考方案5】:

我在 Chrome 49 中关闭视频流轨道(前置摄像头)和打开备用轨道(后置摄像头)时遇到问题。我发现 MediaStream.stop() 自版本 45 以来已被弃用,并已替换为MediaStreamTrack.stop()。您可以通过 Sam Dutton 在 Google 开发者网站上的 posting 了解更多信息。

【讨论】:

【参考方案6】:

为了消除浏览器标签上的红色符号并禁用两者,videoaudio 在收到这些错误之一时流式传输

Uncaught TypeError: localStream.stop is not a function
Uncaught TypeError: _webRTCStream.stop is not a function // TokBox, OpenTok

遍历找到的曲目并将它们全部停止。

if (_webRTCStream.stop) 
  _webRTCStream.stop() // idk what this does, left here for legacy reasons..?
 else 
  _webRTCStream.getTracks().forEach(function(track)  track.stop() )

注意:_webRTCStream 等于 localStream,取决于您使用的库。

【讨论】:

【参考方案7】:
if (sourcevid.mozSrcObject) 
  sourcevid.mozSrcObject.stop();
  sourcevid.src = null;
 else 
  sourcevid.src = "";
  localStream.stop();

【讨论】:

以上是关于在不刷新页面的情况下停止getUserMedia的网络摄像头流[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Django:如何在不刷新页面的情况下更新图像?

Ajax 功能无法在不刷新页面的情况下正常删除

在不刷新页面的情况下检测元掩码安装

如何在不刷新整个页面的情况下重新加载组件?

是否可以在不刷新整个页面的情况下刷新包含的 Django 模板?

在不刷新浏览器的情况下浏览页面