基于 Agora Web SDK 实现一对一视频通话

本文会详细介绍如何建立一个简单的项目并使用 Agora Web SDK 实现基础的一对一视频通话。
image

Demo 体验

我们在 GitHub 上提供一个开源的基础一对一视频通话示例项目,在开始开发之前你可以通过该示例项目体验音视频通话效果。

Github:https://github.com/AgoraIO/Basic-Video-Call/tree/master/One-to-One-Video/Agora-Web-Tutorial-1to1

开发条件

  1. 安装一款 Agora Web SDK 支持的浏览器,如下表所示:
    image
  2. 获得一个有效的 Agora 账号。
    image

设置开发环境

你需要准备一个自己的项目并且将 Agora Web SDK 集成到其中。

创建 Web 项目

如果你已经有一个 Web 项目了,跳过本小节,直接阅读集成 SDK。

我们提供的示例代码使用了一些第三方的库文件来实现页面的样式和布局,你可以访问本文开篇的 Github 地址,在文件夹「vendor」中获得以下文件,或者使用其他方式实现。

  • common.css
  • jquery.min.js
  • materialize.min.js

以下为示例:

这个项目只需要用到一个 HTML 文件。

  1. 新建一个 HTML 文件。这里我们将文件命名为 index.html(以下简称项目文件)。

  2. 用一个代码编辑器(例如 VS Code)打开该文件。

  3. 复制以下代码,粘贴到项目文件中。
    该步骤会为你的项目创建前端页面的 UI。这里我们直接用了 Agora 示例项目中的代码,你也可以自定义你的 UI。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Basic Communication</title>
<link rel="stylesheet" href="./assets/common.css" />
</head>
<body class="agora-theme">
<div class="navbar-fixed">
 <nav class="agora-navbar">
   <div class="nav-wrapper agora-primary-bg valign-wrapper">
     <h5 class="left-align">Basic Communication</h5>
   </div>
 </nav>
</div>
<form id="form" class="row col l12 s12">
 <div class="row container col l12 s12">
   <div class="col" style="min-width: 433px; max-width: 443px">
     <div class="card" style="margin-top: 0px; margin-bottom: 0px;">
       <div class="row card-content" style="margin-bottom: 0px;">
           <div class="input-field">
             <label for="appID" class="active">App ID</label>
             <input type="text" placeholder="App ID" name="appID">
           </div>
           <div class="input-field">
             <label for="channel" class="active">Channel</label>
             <input type="text" placeholder="channel" name="channel">
           </div>
           <div class="input-field">
             <label for="token" class="active">Token</label>
             <input type="text" placeholder="token" name="token">
           </div>
           <div class="row" style="margin: 0">
             <div class="col s12">
             <button class="btn btn-raised btn-primary waves-effect waves-light" id="join">JOIN</button>
             <button class="btn btn-raised btn-primary waves-effect waves-light" id="leave">LEAVE</button>
             <button class="btn btn-raised btn-primary waves-effect waves-light" id="publish">PUBLISH</button>
             <button class="btn btn-raised btn-primary waves-effect waves-light" id="unpublish">UNPUBLISH</button>
             </div>
           </div>
       </div>
     </div>
   </div>
   <div class="col s7">
     <div class="video-grid" id="video">
       <div class="video-view">
         <div id="local_stream" class="video-placeholder"></div>
         <div id="local_video_info" class="video-profile hide"></div>
         <div id="video_autoplay_local" class="autoplay-fallback hide"></div>
       </div>
     </div>
   </div>
 </div>
</form>
<script src="vendor/jquery.min.js"></script>
<script src="vendor/materialize.min.js"></script>
</body>
</html>

集成 SDK

选择如下任意一种方法获取 Agora Web SDK:

方法 一、 使用 npm 获取 SDK

  1. 运行安装命令
npm install agora-rtc-sdk

2.在你的项目的 Javascript 代码中添加一行:

import AgoraRTC from 'agora-rtc-sdk'

方法 二、 使用 CDN 方法获取 SDK

该方法无需下载安装包。在项目文件中,将以下代码添加到 <style> 上一行:

<script src="https://cdn.agora.io/sdk/release/AgoraRTCSDK-3.0.0.js"></script> 

方法 三、 从官网获取 SDK

  1. 下载最新版 Agora Web SDK 软件包。

  2. 将下载下来的软件包中的 AgoraRTCSDK-3.0.0.js 文件保存到项目文件所在的目录下。

  3. 在项目文件中,将如下代码添加到 <style> 上一行:

<script src="./AgoraRTCSDK-3.0.0.js"></script>

为方便起见,这里我们选择第二种方法,直接使用 CDN 链接。

现在,我们已经将 Agora Web SDK 集成到项目中了。接下来我们要通过调用 Agora Web SDK 提供的核心 API 实现基础的音视频通话功能。

实现音视频通话

接下来介绍如何使用 Agora Web SDK 实现音视频通话。

在使用 Agora Web SDK 时,你会经常用到以下两种对象:

  • Client 对象,代表一个本地客户端。Client 类的方法提供了音视频通话的主要功能,例如加入频道、发布音视频流等。

  • Stream 对象,代表本地和远端的音视频流。Stream 类的方法用于定义音视频流对象的行为,例如流的播放控制、音视频的编码配置等。调用 Stream 方法时,请注意区分本地流和远端流对象。

下图展示了基础的一对一音视频通话的 API 调用。注意图中的方法是对不同的对象调用的。
image
image
为方便起见,我们为下面要用到的示例代码定义了两个变量。此步骤不是必须的,你可以根据你的项目有其他的实现。

// rtc object
var rtc = {
  client: null,
  joined: false,
  published: false,
  localStream: null,
  remoteStreams: [],
  params: {}
};

// Options for joining a channel
var option = {
  appID: "Your App ID",
  channel: "Channel name",
  uid: null,
  token: "Your token"
}

加入频道

  1. 加入频道前,我们需要先创建并初始化一个客户端对象。
// Create a client
rtc.client = AgoraRTC.createClient({mode: "rtc", codec: "h264"});

// Initialize the client
rtc.client.init(option.appID, function () {
  console.log("init success");
  }, (err) => {
  console.error(err);
});

AgoraRTC.createClient 方法中,需注意 modecodec 这两个参数的设置:

  1. mode 用于设置频道模式。一对一或多人通话中,建议设为 "rtc" ,使用通信模式;互动直播中,建议设为 "live" ,使用直播模式。

  2. codec 用于设置浏览器使用的编解码格式。如果你需要使用 Safari 12.1 及之前版本,将该参数设为 "h264" ;如果你需要在手机上使用 Agora Web SDK,请参考声网文档中心「移动端使用 Web SDK」页面。

你需要在该步骤中填入项目的 App ID。请参考如下步骤在控制台创建 Agora 项目并获取 App ID:

a. 登录控制台,点击左侧导航栏的项目管理图标

b. 点击创建,按照屏幕提示设置项目名,选择一种鉴权机制,然后点击提交。

c. 在项目管理页面,你可以获取该项目的 App ID。

为方便演示,我们的示例项目在网页上设置了一个文本框用于输入 App ID。在实际的应用中,App ID 应该是在代码中填写的。

  1. Client.initonSuccess 回调中调用 Client.join 加入频道。
// Join a channel
rtc.client.join(option.token ? option.token : null, option.channel, option.uid ? +option.uid : null, function (uid) {
    console.log("join channel: " + option.channel + " success, uid: " + uid);
    rtc.params.uid = uid;
  }, function(err) {
    console.error("client join failed", err)
})

Client.join 中注意以下参数的设置:

更多的参数设置注意事项请参考 Client.join 接口中的参数描述。

  1. 在测试环境,我们推荐使用控制台生成临时 Token,详见获取临时 Token。

  2. 在生产环境,我们推荐你在自己的服务端生成 Token,详见 生成 Token.

  3. token : 该参数为可选。如果你的 Agora 项目开启了 App 证书,你需要在该参数中传入一个 Token。

  4. channel : 频道名,长度在 64 字节以内的字符串。

  5. uid : 用户 ID,频道内每个用户的 UID 必须是唯一的。如果你将 uid 设为 null ,Agora 会自动分配一个 UID 并在 onSuccess 回调中返回。

发布本地流

  1. Client.joinonSuccess 回调中调用 AgoraRTC.createStream 方法创建一个本地音视频流。

在创建流时,通过设置 audiovideo 参数来控制是否发布音频和视频。

// Create a local stream
rtc.localStream = AgoraRTC.createStream({
  streamID: rtc.params.uid,
  audio: true,
  video: true,
  screen: false,
})
  1. 调用 Stream.init 方法初始化创建的流。
// Initialize the local stream
rtc.localStream.init(function () {
  console.log("init local stream success");
}, function (err) {
  console.error("init local stream failed ", err);
})

在初始化流时,浏览器会跳出弹窗要求摄像头和麦克风权限,请确保授权。

  1. Stream.initonSuccess 回调中调用 Client.publish 方法,发布本地流。
// Publish the local stream
rtc.client.publish(rtc.localStream, function (err) {
  console.log("publish failed");
  console.error(err);
})

订阅远端流

当远端流加入频道时,会触发 stream-added 事件,我们需要通过 Client.on 监听该事件并在回调中订阅新加入的远端流。

我们建议在创建客户端对象之后立即监听事件。

  1. 监听 "stream-added" 事件,当有远端流加入时订阅该流。
rtc.client.on("stream-added", function (evt) {
  var remoteStream = evt.stream;
  var id = remoteStream.getId();
  if (id !== rtc.params.uid) {
    rtc.client.subscribe(remoteStream, function (err) {
      console.log("stream subscribe failed", err);
    })
  }
  console.log('stream-added remote-uid: ', id);
});
  1. 监听 "stream-subscribed" 事件,订阅成功后播放远端流。
rtc.client.on("stream-subscribed", function (evt) {
  var remoteStream = evt.stream;
  var id = remoteStream.getId();
  // Add a view for the remote stream.
  addView(id);
  // Play the remote stream.
  remoteStream.play("remote_video_" + id);
  console.log('stream-subscribed remote-uid: ', id);
})

受浏览器策略影响,在 Chrome 70+ 和 Safari 浏览器上, Stream.play 方法必须由用户手势触发,详情请参考 Autoplay Policy Changes。

  1. 监听 "stream-removed" 事件,当远端流被移除时(例如远端用户调用了 Stream.unpublish ), 停止播放该流并移除它的画面。
rtc.client.on("stream-removed", function (evt) {
  var remoteStream = evt.stream;
  var id = remoteStream.getId();
  // Stop playing the remote stream.
  remoteStream.stop("remote_video_" + id);
  // Remove the view of the remote stream.
  removeView(id);
  console.log('stream-removed remote-uid: ', id);
})

我们建议在创建客户端对象之后立即监听事件。

image

离开频道

调用 Client.leave 方法离开频道。

// Leave the channel
rtc.client.leave(function () {
  // Stop playing the local stream
  rtc.localStream.stop();
  // Close the local stream
  rtc.localStream.close();
  // Stop playing the remote streams and remove the views
  while (rtc.remoteStreams.length > 0) {
    var stream = rtc.remoteStreams.shift();
    var id = stream.getId();
    stream.stop();
    removeView(id);
  }
  console.log("client leaves channel success");
}, function (err) {
  console.log("channel leave failed");
  console.error(err);
})

运行你的 app

接下来,以我们的示例项目为例说明如何运行和测试你的 web app。

我们建议在本地 Web 服务器上测试你的 app。这里我们用 npm 的 live-server 设置一个本地 服务器。

在本地服务器(localhost)运行 web app 仅作为测试用途。部署生产环境时,请确保使用 HTTPS 协议。

  1. 安装 live-server。
npm i live-server -g
  1. 在命令行中进入你的项目所在的目录。对于我们的示例项目,该目录位于 /Basic-Video-Call/One-to-One-Video/Agora-Web-Tutorial-1to1。

  2. 运行 app。

live-server .

现在你的浏览器应该会自动打开你的 web app 页面。

  1. 输入你的 App ID,频道名,token,点击 JOIN 开始通话。
    你可能需要给浏览器摄像头和麦克风权限。如果在创建本地流时打开了视频,你现在应该可以看到自己的视频画面。

  2. 在浏览器中打开另一个页面,输入相同的 URL 地址。点击 JOIN 按钮。现在你应该可以看到两个视频画面。

如果页面没有正常工作,可以打开浏览器的控制台查看错误信息进行排查。常见的错误信息包括:

  • INVALID_VENDOR_KEY :App ID 错误,检查你填写的 App ID。

  • ERR_DYNAMIC_USE_STATIC_KE :你的 Agora 项目启用了 App 证书,需要在加入频道时填写 Token。

  • Media access:NotFoundError :检查你的摄像头和麦克风是否正常工作。

  • MEDIA_NOT_SUPPORT :请使用 HTTPS 协议 或者 localhost。

注:Agora Web SDK 不支持在浏览器上模拟移动设备调试。
image

推荐阅读
作者信息
AgoraTechnicalTeam
TA 暂未填写个人简介
文章
153
相关专栏
SDK 教程
55 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和 Agora 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。