Google 致力于为黑人社区推动种族平等。查看具体行动

Firebase + WebRTC Codelab

1.简介

在此 Codelab 中,您将学习如何使用在浏览器中使用 WebRTC API 和 Cloud Firestore 进行信令来构建简单的视频聊天应用。该应用名为 FirebaseRTC,它作为一个简单的示例,将向您介绍构建支持 WebRTC 的应用的基础知识。

{101. }

学习内容

  • 使用 WebRTC 在 Web 应用中发起视频通话
  • 使用 Cloud Firestore 向远程第三方发送信号

所需条件

在开始此 Codelab 之前,请确保您已安装:

  • npm(通常随 Node.js 一起提供)- 建议使用 Node LTS

2. 创建并设置 Firebase 项目

创建 Firebase 项目

  1. 在 Firebase 控制台中,点击“添加项目”,然后将 Firebase 项目命名为 FirebaseRTC。

记住您的 Firebase 项目的 ID。

  1. 点击“创建项目”。

您要构建的应用可以使用网络上可用的两项 Firebase 服务:

  • Cloud Firestore 可将结构化数据保存在云端,并在数据更新时即时获取通知
  • 使用 Firebase Hosting 托管和提供您的静态资源

对于此特定 Codelab,您已在要克隆的项目中配置了 Firebase Hosting。但是,对于 Cloud Firestore,我们将引导您使用 Firebase 控制台配置和启用服务。

启用 Cloud Firestore

该应用使用 Cloud Firestore 保存聊天消息并接收新的聊天消息。

您需要启用 Cloud Firestore:

  1. 在 Firebase 控制台菜单的“开发”部分,点击“数据库”。
  2. 在 Cloud Firestore 窗格中点击创建数据库
  3. 选择以测试模式开始选项,并在阅读有关安全规则的免责声明后点击“启用”。

测试模式可确保您在开发过程中可以随意向数据库写入数据。我们稍后会在此 Codelab 中提高数据库的安全性。

3.获取示例代码

从命令行克隆 GitHub 代码库:

git clone https://github.com/webrtc/FirebaseRTC

示例代码应该已克隆到 FirebaseRTC 目录中。确保从现在起从此目录运行命令行:

cd FirebaseRTC

导入入门版应用

在编辑器中打开 FirebaseRTC 中的文件,并按照以下说明进行更改。此目录包含此 Codelab 的起始代码,其中包含一个尚未正常运行的 WebRTC 应用。在本 Codelab 中,我们将让它正常运行。

4.安装 Firebase 命令行界面

借助 Firebase 命令行界面 (CLI),您可以在本地提供 Web 应用,并将您的 Web 应用部署到 Firebase Hosting。

  1. 通过运行以下 npm 命令来安装 CLI: sh npm -g install firebase-tools
  1. 通过运行以下命令来验证 CLI 是否已正确安装:sh firebase --version

确保 Firebase CLI 版本为 6.7.1 或更高版本。

  1. 通过运行以下命令向 Firebase CLI 授权:sh firebase login

您已设置 Web 应用模板,以从应用的本地目录和文件中提取应用的 Firebase Hosting 配置。但为此,您需要将应用与您的 Firebase 项目相关联。

  1. 通过运行以下命令,将您的应用与 Firebase 项目相关联: sh firebase use --add

  2. 出现提示时,选择您的项目 ID,然后为您的 Firebase 项目指定一个别名。

如果您有多个环境(生产、预演等),别名会非常有用。 不过,在此 Codelab 中,我们直接使用 default 这个别名。

  1. 请按照命令行中的其余说明操作。

5. 运行本地服务器

您现在可以开始实际工作了!让我们在本地运行应用!

  1. 运行以下 Firebase CLI 命令:sh firebase serve --only hosting

  2. 命令行应显示以下响应:hosting: Local server: http://localhost:5000

我们使用 Firebase Hosting 模拟器在本地提供应用。现在,可以从 http://localhost:5000 访问 Web 应用。

  1. 通过 http://localhost:5000 打开您的应用。

您应该会看到已与 Firebase 项目关联的 FirebaseRTC 副本。

该应用已自动连接到您的 Firebase 项目。

6.创建新聊天室

在此应用中,每个视频聊天会话都称为“聊天室”。用户可通过点击应用中的按钮创建新聊天室。此操作将生成一个远程端加入同一聊天室的 ID。系统会将该 ID 用作每个会议室的 Cloud Firestore 中的键。

每个聊天室都将包含优惠和回答的 RTCSessionDescriptions,以及包含各方的候选 ICE 的两个单独集合。

您的第一个任务是实现缺少的代码,以便使用调用方提供的初始优惠创建新房间。打开 public/app.js 并找到注释 // Add code for creating a room here,然后添加以下代码:

const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);

const roomWithOffer = {
    offer: {
        type: offer.type,
        sdp: offer.sdp
    }
}
const roomRef = await db.collection('rooms').add(roomWithOffer);
const roomId = roomRef.id;
document.querySelector('#currentRoom').innerText = `Current room is ${roomId} - You are the caller!`

第一行会创建一个 RTCSessionDescription,用于表示调用方提供的优惠。然后将其设置为本地说明,并最终写入 Cloud Firestore 中的新 Room 对象。

接下来,我们将侦听数据库的变化,并检测被调用方何时添加了应答。

roomRef.onSnapshot(async snapshot -> {
    console.log('Got updated room:', snapshot.data());
    const data = snapshot.data();
    if (!peerConnection.currentRemoteDescription && data.answer) {
        console.log('Set remote description: ', data.answer);
        const answer = new RTCSessionDescription(data.answer)
        await peerConnection.setRemoteDescription(answer);
    }
});

这将等待被调用方为应答写入 RTCSessionDescription,并将其设置为调用方 RTCPeerConnection 的远程说明。

7. 加入聊天室

下一步是实现用于加入现有聊天室的逻辑。用户只需点击加入聊天室按钮并输入要加入的聊天室的 ID 即可。此处的任务是为答案创建 RTCSessionDescription,并相应地更新数据库中的空间。

const offer = roomSnapshot.data().offer;
await peerConnection.setRemoteDescription(offer);
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);

const roomWithAnswer = {
    answer: {
        type: answer.type,
        sdp: answer.sdp
    }
}
await roomRef.update(roomWithAnswer);

在上面的代码中,我们首先从调用方中提取优惠,并创建 RTCSessionDescription 并将其设置为远程说明。接下来,我们创建回答,将其设置为本地说明,并更新数据库。数据库更新将在调用方端触发 onSnapshot 回调,后者进而根据被调用方的回应设置远程说明。这样就完成了调用方与被调用方之间的 RTCSessionDescription 对象交换。

8. 收集 ICE 候选对象

在调用方和被调用方可以连接之前,他们还需要交换 ICE 候选项,告知 WebRTC 如何连接到远程对等端。 您的下一个任务是实现代码以监听 ICE 候选对象并将其添加到数据库的集合中。找到 collectIceCandidates 函数并添加以下代码:

async function collectIceCandidates(roomRef, peerConnection,
                                    localName, remoteName) {
    const candidatesCollection = roomRef.collection(localName);

    peerConnection.addEventListener('icecandidate', event -> {
        if (event.candidate) {
            const json = event.candidate.toJSON();
            candidatesCollection.add(json);
        }
    });

    roomRef.collection(remoteName).onSnapshot(snapshot -> {
        snapshot.docChanges().forEach(change -> {
            if (change.type === "added") {
                const candidate = new RTCIceCandidate(change.doc.data());
                peerConneciton.addIceCandidate(candidate);
            }
        });
    })
}

此函数会执行两项操作。它通过 WebRTC API 收集 ICE 候选对象并将其添加到数据库中,并通过远程对等方监听已添加的 ICE 候选对象并将其添加到其 RTCPeerConnection 实例中。在监听数据库更改以滤除任何新增内容时,这一点非常重要,因为我们原本会反复添加同一组 ICE 候选对象。

9. 总结

在此 Codelab 中,您学习了如何使用 Cloud Firestore 实现 WebRTC 的信号处理,以及如何使用它创建简单的视频聊天应用。

要了解详情,请访问以下资源:

  1. FirebaseRTC 源代码
  2. WebRTC 示例
  3. Cloud Firestore