WebRTC/getUserMedia:如何正确静音本地视频?

Posted

技术标签:

【中文标题】WebRTC/getUserMedia:如何正确静音本地视频?【英文标题】:WebRTC/getUserMedia: How to properly mute local video? 【发布时间】:2014-01-15 06:43:30 【问题描述】:

我正在尝试在我的 WebRTC 应用程序中实现将本地视频 MediaStreamTrack 静音的功能。以下是我的处理方式:

function muteVideo() 
  if (this._localStream && this._localStream.getVideoTracks().length > 0) 
    this._localStream.getVideoTracks()[0].enabled = false;
  

在 Firefox 中,本地流附加到的 <video> 元素在静音时正确呈现黑色。在 Chrome 中,不会渲染黑色,但图片会冻结。但是,在这两种浏览器中,相机的绿灯一直亮着,这显然是不受欢迎的行为。 (我希望我的用户在视频静音时看到应用程序实际上断开与摄像头的连接。)

如果我这样做this._localStream.stop(),相机的灯就会熄灭,但随后音频也会熄灭。

Media Capture 规范的 current draft 提到了 MediaStreamTrack.stop() 方法,但它目前似乎未在 Chrome 和 Firefox 中实现。

那么有没有办法在以下情况下将本地视频静音:

    关闭相机灯 没有丢失音轨?

【问题讨论】:

【参考方案1】:

今天

track.stop() 在 Firefox 中运行良好。铬在后面。指定结束曲目的方式(https fiddle):

navigator.mediaDevices.getUserMedia(video: true, audio: true)
  .then(stream => video.srcObject = stream)
  .catch(e => log(e.name + ": "+ e.message));

let stop = k => video.srcObject.getTracks().map(t => t.kind == k && t.stop());
<video id="video"   autoplay></video><br>
<button onclick="stop('video')">Stop Video</button>
<button onclick="stop('audio')">Stop Audio</button>

这为您提供了一种在保留音频的同时关闭视频的方法,无需在 Firefox 中重新提示。重新打开视频时您仍然会收到提示,因此它并不完美,但要好 50%。

在 Chrome 赶上之前,您的其他答案(每次 drop 和 re-gUM)应该在那里工作,因为它们永远不会重新提示。

通过浏览器检测和组合这些答案,应该可以提出在多个浏览器中运行良好的东西,直到浏览器赶上来。

长期

该规范最近 addressed this 允许浏览器在暂时静音期间关闭摄像头灯(例如 track.enabled == false),前提是摄像头访问指示灯保持亮起:

“鼓励用户代理提供任何可访问的当前状态的持续指示。

鼓励用户代理提供 anyLive 当前状态的持续指示,并使任何通用硬件设备指示灯匹配。”

规范中的这些语句之前使用了更强大的语言,从而使指标成为一项要求。

目前,浏览器没有正确实现这一点。 Chrome 已关闭,最近访问后右侧 url 栏内有一个微小的摄像头访问指示器,但它未能出现在页面加载中,以警告上次访问已授予持久访问权限;该网站可以随时打开摄像头。

【讨论】:

问题的重点是找到一个今天不管规范说什么都行得通的解决方案。 3年后,规范的做事方式行不通。 @jamix 我为您提供了一种在保留音频的同时关闭视频的方法,而无需在今天的 Firefox 中重新提示许可。这超过了您的自我回答,它会在 Firefox 中重新提示 两次(一次是在视频消失时,一次是在它重新打开时)。通过浏览器检测和组合这些答案,您应该能够提出在多个浏览器中运行良好的东西,直到浏览器赶上来。几乎不值得投反对票。 是的,依赖于浏览器的行为确实会使 Firefox 中的 UX 更好,感谢您的建议。我不能再取消反对票,但如果您编辑答案(相应地?),我将能够取消。【参考方案2】:

我认为您可以对 getuser media 提出两个请求:http://codepen.io/anon/pen/gjtpu。然后你就可以真正停止流了。您还必须在用户之间使用多个对等连接,因为 firefox 不支持重新协商(在现有对等连接期间添加或删除流)

【讨论】:

谢谢。但是根据 WebRTC 草案,MediaStreamTracks 如果属于不同的MediaStreams,则不一定必须同步。恐怕这会导致音频/视频同步问题。 你是对的,它会导致同步问题。但是关闭灯的唯一方法是真正停止流(因此您必须在重新启动之前再次请求许可) 您应该能够使用stream.addTrackstream.removeTrack,甚至new MediaStream([videoTrack, audioTrack])(规范和Firefox,在今天的Chrome 中的一个标志后面),将曲目组合成一个新的流。至少在理论上应该重新同步它们,但我没有尝试过。如果没有,则为错误。【参考方案3】:

我们通过拆除本地媒体流并在没有视频轨道的情况下重新创建它来解决这个问题。在通话中执行此操作需要重新建立对等连接或执行重新协商(由发送新报价触发)。

【讨论】:

以上是关于WebRTC/getUserMedia:如何正确静音本地视频?的主要内容,如果未能解决你的问题,请参考以下文章

静音流轨道Twilio js的音频/视频

sql server 将字符串第二字符替换为另外一个字符的 方法

深耕静禅_Java_注解_2020年4月5日21:44:24

当你的才华还撑不起你的野心时,就应该静下心来学习

物理-电磁力/静电力:百科

静电场分析