发布于 2026-01-06 1 阅读
0

9分钟内用JavaScript和Twilio CLI构建视频应用

9分钟内用JavaScript和Twilio CLI构建视频应用

视频标题

这篇博文是为Twilio撰写的,最初发表在 Twilio 博客上

现在很多人都在远程办公,视频聊天非常流行。这里介绍如何使用Twilio Programmable VideoTwilio Serverless Toolkit,在九分钟内用 JavaScript 搭建一个视频聊天室
示例图片

设置

要构建一个 Twilio 可编程视频应用程序,我们需要:

请将您的 API 密钥保存在您方便访问的位置,然后通过 Twilio CLI安装 Twilio Serverless Toolkit(如果您尚未安装)。安装方法如下:运行以下命令

twilio plugins:install @twilio-labs/plugin-serverless
Enter fullscreen mode Exit fullscreen mode

然后,您可以通过运行以下命令来查看 Serverless Toolkit 提供的命令。

twilio serverless
Enter fullscreen mode Exit fullscreen mode

创建无服务器项目

通过在命令行运行命令,使用空白模板创建一个 Serverless 项目。

twilio serverless:init --template blank {insert-project-name}
Enter fullscreen mode Exit fullscreen mode

将 `<project_name>`替换{insert-project-name}为你的项目名称——我的项目名称是 `<project_name>` tfvideo。命令执行完毕后,将在当前目录下创建一个以项目名称命名的目录。

项目目录包含一些现成的文件夹。在 `<project_directory>`文件夹中functions,添加一个名为 ` video-token.js<file_name>` 的文件;在 `<assets>` 文件夹中,添加两个文件:` <file_name>`video.html和 ` <file_name>`。index.js在 `<file_name>` 中设置环境变量。您可以保留包含 `<environment_variables>`和`<environment_variables>` 的.env前两行。在它们下方,添加您的账户 SID、API 密钥和 API 密钥:ACCOUNT_SIDAUTH_TOKEN
环境

生成访问令牌

添加functions/video-token.js以下代码以生成访问令牌。这里我们设置了环境变量、固定的房间名称以及ACCESS_TOKEN_IDENTITY每个用户的访问权限。每个用户都将被授予房间访问权限tf。此代码修改自此页面,该页面还包含有关访问令牌的更多信息

exports.handler = function(context, event, callback) {
    const TWILIO_ACCOUNT_SID = context.TWILIO_ACCOUNT_SID;
    const TWILIO_API_KEY = context.TWILIO_API_KEY;
    const TWILIO_API_SECRET = context.TWILIO_API_SECRET;
    const ACCESS_TOKEN_IDENTITY =
      Math.random()
        .toString(36)
        .substring(2, 15) +
      Math.random()
        .toString(36)
        .substring(2, 15);  // random client name 

    const ROOM_NAME = 'tf';  // fixed room name
    const AccessToken = Twilio.jwt.AccessToken;
    const VideoGrant = AccessToken.VideoGrant;
    // only tokens are available for participating rooms
    // Create a Video grant enabling client to use Video, only for this room 
    const videoGrant = new VideoGrant({
        room: ROOM_NAME
    });
    //Create an access token to sign and return to the client with the grant we just created
    const accessToken = new AccessToken(
        TWILIO_ACCOUNT_SID,
        TWILIO_API_KEY,
        TWILIO_API_SECRET
    );
    accessToken.addGrant(videoGrant); //Add the grant to the token
    accessToken.identity = ACCESS_TOKEN_IDENTITY;
    callback(null, {
        token: accessToken.toJwt() //Serialize the token to a JWT string
    });
};
Enter fullscreen mode Exit fullscreen mode

制作我们的视频网站

现在打开你之前创建的空白assets/video.html文件。我们将编写一些基本的 HTML 代码,包括加入和离开房间的按钮、一个会自动显示用户摄像头预览的视频标签、index.js我们即将编写的文件,以及 Axios 和 Twilio Video.js 库:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Twilio Video Serverless Demo</title>
</head>
  <body>
    <div id="room-controls">
      <video id="video" autoplay muted="true" width="320"
          height="240"></video>
      <button id="button-join">Join Room</button>
      <button id="button-leave" disabled>Leave Room</button>
    </div>

  <script src="//media.twiliocdn.com/sdk/js/video/releases/2.3.0/twilio-video.min.js"></script>
  <script src="https://unpkg.com/axios@0.19.0/dist/axios.min.js"></script>
  <script src="index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

构建视频应用

添加assets/index.js以下代码。简而言之,这段可复制粘贴的脚本将执行以下操作:

  • 将无服务器域名(这将是基本 URL)设置为您使用 CLI 模板为项目命名的名称。
  • 设置房间名称和一些变量
  • 获取视频元素并将其显示在预览屏幕中
  • 当用户加入房间时,使用axio对文件的 s 调用生成访问令牌。video-token
  • tf当用户点击button-join或单击时,将用户连接到房间或断开用户与房间的连接。button-leave
  • 通过附加事件监听器来订阅或取消订阅远程参与者的频道,从而显示他们的视频tf。如果他们已经在房间中,我们会遍历现有的频道participants并附加事件监听器trackSubscribed

如果更改房间名称,则必须同时更改生成的令牌。

(() => {
    'use strict';
    const TWILIO_DOMAIN = location.host; //unique to user, will be website to visit for video app
    const ROOM_NAME = 'tf';
    const Video = Twilio.Video;
    let videoRoom, localStream;
    const video = document.getElementById("video");

    // preview screen
    navigator.mediaDevices.getUserMedia({video: true, audio: true})
    .then(vid => {
        video.srcObject = vid;
        localStream = vid;
    })

    // buttons
    const joinRoomButton = document.getElementById("button-join");
    const leaveRoomButton = document.getElementById("button-leave");
    var site = `https://${TWILIO_DOMAIN}/video-token`;
    console.log(`site ${site}`);
    joinRoomButton.onclick = () => {
      // get access token
      axios.get(`https://${TWILIO_DOMAIN}/video-token`).then(async (body) => {
        const token = body.data.token;
        console.log(token);

        Video.connect(token, { name: ROOM_NAME }).then((room) => {
          console.log(`Connected to Room ${room.name}`);
          videoRoom = room;

          room.participants.forEach(participantConnected);
          room.on("participantConnected", participantConnected);

          room.on("participantDisconnected", participantDisconnected);
          room.once("disconnected", (error) =>
            room.participants.forEach(participantDisconnected)
          );
          joinRoomButton.disabled = true;
          leaveRoomButton.disabled = false;
        });
      });
    };
    leaveRoomButton.onclick = () => {
      videoRoom.disconnect();
      console.log(`Disconnected from Room ${videoRoom.name}`);
      joinRoomButton.disabled = false;
      leaveRoomButton.disabled = true;
    };
})();

const participantConnected = (participant) => {
    console.log(`Participant ${participant.identity} connected'`);

    const div = document.createElement('div');
    div.id = participant.sid;

    participant.on('trackSubscribed', track => trackSubscribed(div, track));
    participant.on('trackUnsubscribed', trackUnsubscribed);

    participant.tracks.forEach(publication => {
      if (publication.isSubscribed) {
        trackSubscribed(div, publication.track);
      }
    });
    document.body.appendChild(div);
}

const participantDisconnected = (participant) => {
    console.log(`Participant ${participant.identity} disconnected.`);
    document.getElementById(participant.sid).remove();
}

const trackSubscribed = (div, track) => {
    div.appendChild(track.attach());
}

const trackUnsubscribed = (track) => {
    track.detach().forEach(element => element.remove());
}
Enter fullscreen mode Exit fullscreen mode

是的,可编程视频技术已经变得简单易懂了!

在命令行中运行命令twilio serverless:deploy。CLI 会祝贺您Serverless 项目已成功部署,并提供一些其他部署详情。您可以删除或忽略functions/blank.js使用自动生成的资源部署的内容。获取video.htmlURL Assets,分享给您的朋友,!您就拥有了自己的视频会议室,可以在需要快速视频通话时使用和分享。
与 Mica、Tilde 进行更大规模的群组通话

这个应用功能比较简陋,但考虑到没有编写 CSS 代码,已经相当不错了,对吧?完整的代码可以在 GitHub 上找到

接下来会发生什么?

Twilio 的 Serverless Toolkit 让应用托管变得轻松快捷。接下来,您可以编写更多 CSS 来美化应用,添加可编程聊天功能更多 Twilio 视频功能,获取用户姓名并在聊天时显示,等等。欢迎在线或在评论区告诉我您正在开发什么。

文章来源:https://dev.to/twilio/build-a-video-app-with-javascript-and-the-twilio-cli-in-9-minutes-4fol