WebRTC 非常棒,但它有点难以上手。上周,我和我在 &yet 的同事发布了几款工具,我们希望这些工具能够帮助人们更容易地使用 WebRTC,并真正发挥其作用。
作为这些工具的演示,我们很快构建了一个名为 conversat.io 的简单产品,它允许您创建免费的多用户视频通话,无需帐户和插件,只需在现代浏览器中访问一个 URL 即可。任何访问同一 URL 的人都可以加入通话。
conversat.io 的用途有两个方面。首先,它是一个有用的通信工具。我们的团队使用 And Bang 进行任务和群聊,因此能够将视频对话“房间”的链接放到我们的团队聊天中,供其他人加入,非常有用。其次,它是 SimpleWebRTC.js 库 和运行它的小型 信令服务器 signalmaster 的演示。
(SimpleWebRTC 和 signalmaster 都已在 Github 上开源,并采用 MIT 许可证。帮助我们改进它们!)
关于浏览器支持的快速说明
WebRTC 目前仅在 Chrome 稳定版和 Firefox Nightly 版(在 about:config 中启用 media.peerconnection.enabled
首选项)中有效。
希望我们很快就能看到更广泛的浏览器支持。我特别期待在智能手机和平板电脑上使用 WebRTC。
易用性和采用率
我坚信,新 Web 技术的广泛采用与它们的使用难易程度直接相关。当我还是一名新手 JS 开发者时,正是 jQuery 的易用性让我感觉自己有能力构建很酷的东西。
我开始爱上 JavaScript,一切都是从用 jQuery 做这件事开始的
$('#demo').slideDown();
然后看到元素在我的屏幕上移动。我什么都不懂。但尽管听起来很俗套,但这个简单的操作让我感觉自己有能力构建更有趣的东西。
Socket.io 对那些想要构建从服务器向客户端推送数据的应用程序的人来说也产生了同样的影响
// server:
client.emit("something", {
some: "data"
});
// client:
socket = io.connect();
socket.on("something", function (data) {
// here's my data!
console.log(data);
});
我不必再弄清楚如何设置长轮询、BOSH 和 XMPP 以将数据推送到浏览器,我现在只需向浏览器发送消息即可。事实上,如果我不想这样做,我甚至不必考虑序列化和反序列化。我现在可以无缝地在客户端和服务器之间来回传递简单的 JavaScript 对象。
我听说一些“硬核”开发者抱怨,像这样的工具会导致太多制作粗糙的工具,以及太多“想当然”的开发者,他们不知道自己在做什么。这是无稽之谈。
易用的工具让开发者感觉自己有能力构建很酷的东西,这是 Web 如此成功和充满活力的原因。
像这样的工具是让我们沉迷于构建此类技术上的东西的入门级药物。它们介绍了这个概念,并帮助我们思考可以构建什么。我们最终是否使用最初让我们接触到它的简单工具来构建最终的应用程序,这无关紧要。
WebRTC 的潜力
我相信 WebRTC 有可能对我们的沟通方式产生巨大的影响。它已经对我们在 &yet 的团队产生了影响。当然,我们之前也使用过 Skype、Facetime 和 Google Hangouts 等工具。但是,只需在浏览器中打开一个 URL 即可立即开始对话的简单性和便利性非常强大。
一旦这项技术得到广泛应用并在移动设备上可用,它将彻底改变通信方式。
挑战
确实有一些障碍阻碍了人们随意使用 WebRTC:实例化对等连接的复杂性和浏览器差异、生成和处理信令消息以及将媒体流附加到视频元素。
即使在您拥有这些功能之后,您仍然需要一种方法让两个用户互相找到,并为每个用户提供一种机制,以便将正确的信令消息直接发送到他们想要连接到的其他用户。
SimpleWebRTC.js 是我们针对客户端复杂性的解决方案。它抽象了 Firefox 和 Chrome 之间的 API 差异。
使用 SimpleWebRTC
最简单的方法是,您只需要包含 SimpleWebRTC.js 脚本,并为您的本地视频提供一个容器,为远程视频提供一个容器,如下所示
然后,您只需初始化一个 webrtc
对象并告诉它使用哪些容器
var webrtc = new WebRTC({
// the id of (or actual element) to hold "our" video
localVideoEl: 'localVideo',
// the id of or actual element that will hold remote videos
remoteVideosEl: 'remoteVideos',
// immediately ask for camera access
autoRequestMedia: true
});
此时,如果您运行上面的代码,您将看到您的视频打开并在您提供的容器中呈现。
下一步是实际指定您要连接到的对象。
为了简单起见,并最大程度地提高“可操作性”,我们要求两个想要互相连接的用户加入同一个“房间”,这基本上意味着:使用相同的字符串调用“join”。
因此,出于演示目的,我们只需在我们的 webrtc
准备好后(意味着它已连接到信令服务器)告诉它加入某个房间即可。我们这样做:
// we have to wait until it's ready
webrtc.on('readyToCall', function () {
// you can name it anything
webrtc.joinRoom('your awesome room name');
});
一旦用户执行了此操作,他/她就已准备好并等待其他人加入。
如果您想在本地测试它,您可以将其在 Firefox 和 Chrome 中打开,或者在 Chrome 中的两个选项卡中打开。(Firefox 尚未允许两个选项卡同时访问本地媒体)。
此时,您应该会自动连接并与自己进行热烈的(可能非常有回声的!)对话。
如果您碰巧是我,它看起来像这样
信令服务器
上面的示例将连接到我们一直运行的沙盒信令服务器,以便人们更容易地使用这些功能。
我们的目标是让它可供人们使用,以便他们可以玩 SimpleWebRTC,但它绝对不适合生产使用,我们可能会随时关闭或重新启动它。
如果您想实际构建一个依赖它的应用程序,您可以自己运行一个,或者如果您不想费心,我们可以为您托管、更新和帮助扩展一个。该服务器的代码位于 github 上。
您可以通过在初始化 webrtc
对象时传递“url”选项,将 URL 传递到不同的信令服务器作为配置的一部分。
那么,它在后台到底做了什么?
实际上并不复杂。您可以在此处阅读客户端库的完整源代码:https://github.com/HenrikJoreteg/SimpleWebRTC/blob/master/simplewebrtc.js,以及此处阅读信令服务器的完整源代码:https://github.com/andyet/signalmaster/blob/master/server.js
在 conversat.io 中启动视频通话的过程大致如下
-
建立与信令服务器的连接。它使用 socket.io 并连接到我们在 http://signaling.simplewebrtc.com:8888 上的沙盒信令服务器。
-
通过调用浏览器前缀的
getUserMedia
请求访问本地视频摄像头。 -
创建或获取本地视频元素,并将我们从
getUserMedia
获取的流附加到视频元素。firefox
element.mozSrcObject = stream; element.play();
webkit
element.autoplay = true; element.src = webkitURL.createObjectURL(stream);
-
调用
joinRoom
,它会向信令服务器发送 socket.io 消息,告诉它想要连接到的房间名称。信令服务器将根据情况创建房间(如果不存在)或加入房间(如果存在)。我所说的“房间”仅仅是指特定的 socket.io 会话 ID 按房间名称分组,以便我们可以将有关人员加入/离开该房间的消息仅广播给连接到该房间的客户端。 -
现在,我们玩一个很棒的火箭着陆游戏,该游戏由 @fritzy 在我们等待其他人加入我们时编写的:
-
当其他人加入同一个“房间”时,我们会将其广播给其他已连接的用户,并创建一个我们定义的
Conversation
对象,该对象包装了浏览器的peerConnection
。正如您可能猜到的那样,对等连接表示您与另一人的连接。 -
信令服务器将新的 socket.io 会话 ID 广播到房间中的每个用户,并且每个用户的客户端都会为房间中的每个其他用户创建一个 Conversation 对象。
-
此时,我们有了一种机制来知道要连接到谁以及如何向其每个会话发送直接消息。
-
现在,我们使用 peerConnection 创建一个“offer”,存储我们的本地 offer 并将其设置为我们 peerConnection 中的本地描述。这包含有关其他客户端如何访问和与我们的浏览器通信的信息。
peerConnection.createOffer();
然后,我们通过我们的 socket.io 连接将其发送到房间中的其他人。
-
当客户端收到 offer 时,我们会将其添加到我们的 peerConnection 中
var remote = new RTCSessionDescription(message.payload); peerConnection.setRemoteDescriptionremoteDescription);
并通过调用
peerConnection.createAnswer()
生成一个 answer,并将其发送回我们收到 offer 的人。 -
收到 answer 后,我们将其设置为远程描述。然后,我们创建并发送 ICE 候选者,方法与之类似。这将协商我们的连接并建立连接。
-
如果该过程成功,我们将从我们的 peerConnection 获取
onaddstream
事件,然后我们可以创建一个视频元素并将该流附加到它。此时,视频通话应该正在进行中。
如果您希望进一步深入研究,请向 github 上的 SimpleWebRTC 项目 发送拉取请求和提交问题。
未来的道路
这只是一个开始。帮助我们改进这些功能!
我们希望在这方面看到更多内容
- 使信令部分更具可插拔性(以便您可以使用任何您想要的信令)。
- 添加对暂停和恢复视频/音频的支持。
- 能够确定谁在说话并在该状态更改时向其他已连接的用户发出事件将非常棒。
- 更好地控制处理/拒绝传入请求。
- 设置最大连接数,也许是根据 HTML5 连接 API 确定?
如果您使用这些功能做了一些很酷的事情,或者遇到了问题,或者只是想讨论一下,请在 Twitter 上联系我 (@henrikjoreteg)。我很乐意听取您的意见。
继续构建很棒的东西,你们这些了不起的 Web 人们!互联网万岁!
关于 Henrik Joreteg
Henrik Joreteg 是 &yet 的合伙人,在那里他用几十种方法编写了数十个实时应用程序。在 &yet,他致力于 And Bang 并提供有关 JavaScript 和 HTML5 应用程序的咨询和培训。Henrik 还策划了 RealtimeConf 和 Keeping it Realtime Newsletter。他认为 WebRTC 是多年来最有趣的 Web 技术。
关于 Robert Nyman [荣誉编辑]
Mozilla Hacks 的技术布道者和编辑。发表演讲和博客文章,主题涵盖 HTML5、JavaScript 和开放 Web。Robert 坚定地相信 HTML5 和开放 Web,并且自 1999 年以来一直从事 Web 前端开发工作——在瑞典和纽约市。他还在 http://robertnyman.com 上定期发表博客文章,并且热爱旅行和结识新朋友。
27 条评论