【问题标题】:create and transmit custom mediastream in webrtc在 webrtc 中创建和传输自定义媒体流
【发布时间】:2015-03-06 05:15:15
【问题描述】:

我想用canvas元素作为webrtc通信视频部分的mediastreamsource,任何方向都会有帮助,搜遍了网络,没有找到太多讨论这个话题的资源

* 长篇背景故事 *

问题,我无法直接从相机发送视频,这是我在显示之前处理视频(一些图像处理内容,超出此问题的范围)的要求的一部分。

以前,在其他对等点的浏览器上,我没有使用<video> 标签直接显示视频,而是对隐藏的画布元素进行了一些处理,然后将详细信息复制到另一个画布(我使用了 settimeout 来保持绘图,这给了illusion of live video)。

现在,客户端希望在传输视频之前完成处理,所以我使用 webrtc 直接传递音频流(之前音频和视频都是通过 webrtc 发送的)。对于视频流,我有两种解决方案:

步骤:

  1. 在本地对等点处理视频,在隐藏的画布上绘制。最简单的部分。

  2. 使用超时重复捕获图像数据并传输
    a) 使用websockets( yes, goes through server),它带来了可怕的延迟并最终导致浏览器崩溃。
    b) 使用RTCDataChannel,它的性能要好得多,但有时会无缘无故地失败。我还遇到了其他几个问题(例如,使用的额外带宽,因为发送 jpeg 而不是 webp)。

另一个主要问题是因为我正在使用超时:当我切换标签时,另一边的帧速率下降。

那么,有什么方法可以使用隐藏的画布作为媒体流源,而不是我手动操作?

【问题讨论】:

  • 你能限制使用 Firefox 吗?你也许可以用mozCaptureStreamUntilEnded 来做一些事情。或者我能想到的唯一其他方法是通过某种 MCU 中继媒体(例如 Janus-Gateway 或 Licode 的 Erizo)
  • 很遗憾,它需要同时支持frefox和chrome,我想到了mozCaptureStreamUntilEnded路由,但是在firefox中也需要预先录制的媒体对吗?
  • 可能有一些东西可以一起被破解,并且仍然会使用超时来捕获画布,Jesup 在他的回答中提到了这一点。

标签: javascript webrtc mediastreamsource rtcdatachannel


【解决方案1】:

找到了一个可能的解决方案,至少对于 Firefox,它正在使用画布并捕获它的流并使用 canvas.captureStream() 传输它

// Find the canvas element to capture
var canvasElt = document.getElementsByTagName("canvas")[0];

// Get the stream
var stream = canvasElt.captureStream(25); // 25 FPS

// Do things to the stream
// E.g. Sent it to another computer using a RTCPeerConnection
//      pc is a RTCPeerConnection created elsewhere
pc.addStream(stream);

【讨论】:

  • 您好,我正在尝试相同的方法(从本地视频捕获图像并转换为 base64 并将其分离为块并通过数据通道发送。)但正如您所说,它很慢。这种新方法的性能明显更好吗?我希望这些图像看起来像在其他客户端上播放的视频。
  • @mido:你好,你能回答这个问题吗?stackoverflow.com/questions/62602079/…
【解决方案2】:

mozCaptureStreamUntilEnded 将成为 Martin Thompson 正在为 WG 制定的提案的基础,以直接连接到 MediaStream。根据 cmets 在 Firefox 中的解决方法是 mozCaptureStreamUntilEnded 来自从 MediaStream 捕获的画布的馈送。一个丑陋的序列,这也是我们允许将 a 直接输出到 MediaStream 的部分原因(并且还标准化了 captureStream)。

请注意,将 mozCaptureStream(UntilEnded) 提供给 PeerConnection 已经中断了一段时间(部分原因是到目前为止它是非标准的);它已在 Firefox 36 中修复(将在 6 周后发布频道;下周将进入 Beta 版)。请参阅错误 1097224 和错误 1081409

Chrome 和 Firefox 上令人难以置信的 hacky 方式会将视频放在一个窗口中,然后截屏该窗口。我不建议这样做,因为它需要屏幕共享权限、选择窗口等。

Chrome(或 Firefox)的唯一其他选择是将视频帧保存为 JPEG(正如您提到的)并通过 DataChannel 发送。有效的 Motion-JPEG,但由 JS 运行。帧率和质量(和延迟)会受到影响。您可能希望使用不可靠的通道,因为出现错误时您可以丢弃帧并仅解码下一个(毕竟它是 MJPEG)。此外,如果延迟太高,请减小帧大小!您需要估计端到端延迟;最好的方法是通过数据通道将解码时间反馈给发送方,并让它使用该数据包的接收时间来估计延迟。比起绝对值,你更关心延迟的变化!!

【讨论】:

  • 当您解决 WebRTC 问题时,我总是很高兴,因为我们知道我们得到了准确的信息 :)。
  • @jesup,使用数据通道我面临两个问题,一个:如果对等更改选项卡,超时调用会变慢,因此视频从 10 fps 减慢到 1-2 fps,并且出于某种原因(无法调试),一段时间后,通道(readyState 仍然open)只是停止传输数据,最糟糕的是,没有迹象表明它停止了(仍然调用超时函数,我必须查看其他对等屏幕并弄清楚它停止了)...
  • @mido22 setTimeout 在 JS 中的调用总是在焦点转移到另一个选项卡时在所有浏览器中减少频率或停止(或减少然后停止)。这是非常有意的。您可以尝试使用某种形式的 Worker,但我不确定这是否可行。您确实会正常收到其他事件,因此您可能能够获得反向​​流量来驱动您的捕获(不完美,但可能有效 - 让客户端通过 setTimeouts 发送“给我一个帧”,并在您收到这些帧时抓取帧。很好的副作用:如果客户端停止观看标签,请求会变慢/停止。
  • 是的,即使我得出了类似的结论,我已经使用了太多的网络工作者(用于媒体录制目的),所以我尝试使用其他对等点请求每个帧,但如果选项卡没有任何改进处于非活动状态:(
  • 传入的数据通道 onmessage 或 websocket onmessage 应该立即发生,因此如果您的选项卡立即处于非活动状态,您应该能够响应这些消息。如果没有,请尝试每晚使用 NSPR_LOG_MODULES=datachannel:5,timestamp NSPR_LOG_FILE=whatever
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 2015-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-17
相关资源
最近更新 更多