7

我想使用 canvas 元素作为 webrtc 通信的视频部分的媒体流源,任何方向都会有帮助,在网上搜索,没有找到太多讨论这个话题的资源

*长背景故事*

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

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

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

脚步:

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

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

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

那么,有什么方法可以将隐藏的画布用作媒体流源,而不是我手动进行呢?

4

2 回答 2

3

mozCaptureStreamUntilEnded 将成为 Martin Thompson 正在为 WG 制定的提案的基础,以直接连接到 MediaStream。根据此处的评论,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)。此外,如果延迟太高,请减小帧大小!您需要估计端到端延迟;最好的方法是通过数据通道将解码时间反馈给发送方,并让它使用该数据包的接收时间来估计延迟。您更关心延迟的变化而不是绝对值!

于 2015-01-09T14:42:01.070 回答
0

找到了一个可能的解决方案,至少对于 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);
于 2015-09-04T01:46:05.410 回答