Skip to content
This repository has been archived by the owner on Oct 14, 2022. It is now read-only.

Commit

Permalink
v4.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
disoul committed Jul 15, 2020
1 parent 9188f6a commit 24decb9
Show file tree
Hide file tree
Showing 94 changed files with 1,506 additions and 889 deletions.
Binary file removed Docs/cn/assets-cn/agora-encryption.png
Binary file not shown.
Binary file removed Docs/cn/assets-cn/cloud-proxy.jpeg
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ console.log("create audio file track success");
使用音频文件创建轨道后,如果直接调用 `audioFileTrack.play()` 或者 `client.publish([audioFileTrack])`,你会发现无论是本地还是远端都无法听到音乐声。这是因为通过音频文件创建的音频轨道在音频数据的处理流程上和麦克风音频轨道 (`MicrophoneAudioTrack`) 不同。

**MicrophoneAudioTrack**
![](assets-cn/microphone_audio_track.png)
![](assets/microphone_audio_track.png)

对于麦克风音频轨道来说,SDK 会源源不断地从目标麦克风设备中采集最新的音频数据(`AudioBuffer`)。

Expand All @@ -39,7 +39,7 @@ console.log("create audio file track success");
一旦麦克风音频轨道被创建,采集操作就会持续进行,直到调用 `close()` 方法才会停止,此时音频轨道也将不再可用。

**BufferSourceAudioTrack**
![](assets-cn/buffer_source_audio_track.png)
![](assets/buffer_source_audio_track.png)

对于音频文件来说,SDK 无法采集音频数据,只能通过读取文件达到类似的效果,也就是上图的 `processing` 过程。

Expand Down
File renamed without changes.
204 changes: 204 additions & 0 deletions Docs/cn/basic_call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
---
id: basic_call
title: 实现基本音视频通话
sidebar_label: 实现基本通话
---

本文介绍如何使用 Agora Web SDK NG 实现基本音视频通话。

> 由于浏览器的安全策略对除 127.0.0.1 以外的 HTTP 地址作了限制,Agora Web SDK NG 仅支持 HTTPS 协议或者 http://localhost(http://127.0.0.1)。请勿使用 HTTP 协议在 http://localhost(http://127.0.0.1) 之外访问你的项目。
## 常用对象
在使用 Agora Web SDK NG 时,你会经常用到以下三种对象:

- [AgoraRTCClient](/api/en/interfaces/iagorartcclient.html) 对象,代表一个本地客户端。`AgoraRTCClient` 类的方法提供了音视频通话的主要功能,例如加入频道、发布音视频轨道等。
- [LocalTrack](/api/en/interfaces/ilocalaudiotrack.html) 对象和 [RemoteTrack](/api/en/interfaces/iremotetrack.html) 对象,代表本地和远端的音视频轨道对象,用于播放等音视频相关的控制。

> 音视频流由音视频轨道构成。在 Agora Web SDK NG 中,我们通过操作音视频轨道对象来控制音视频流的行为。
## 基本流程
一次简单的音视频通话的步骤一般如下:
1. 根据项目的 App ID 创建一个本地客户端 `AgoraRTCClient` 对象。
2. 通过 `AgoraRTCClient.join` 加入到一个指定的频道中。
3. 通过麦克风采集的音频创建一个 `MicrophoneAudioTrack` 对象(本地音频轨道对象);通过摄像头采集的视频创建一个 `CameraVideoTrack` 对象(本地视频轨道对象)。
4. 通过 `AgoraRTCClient.publish` 将创建的本地音视频轨道对象发布到频道中。

当有其他用户加入频道并且也发布音视频轨道时:
1. SDK 会触发 `client.on("user-published")` 事件,在这个事件回调函数的参数中你可以拿到远端用户对象 `AgoraRTCRemoteUser`,表示这个用户刚刚发布了音视频轨道。
2. 通过 `AgoraRTCClient.subscribe` 订阅获取到的 `AgoraRTCRemoteUser`
3. 订阅完成后,访问 `AgoraRTCRemoteUser.audioTrack``AgoraRTCRemoteUser.videoTrack` 即可获取到 `RemoteAudioTrack`(远端音频轨道对象)和 `RemoteVideoTrack`(远端视频轨道对象)。

为方便起见,我们预定义了两个变量和一个函数,下面的所有示例代码都包裹在这个函数中。此步骤不是必须的,你可以根据你的项目有其他的实现。

```js
const rtc = {
// 用来放置本地客户端。
client: null,
// 用来放置本地音视频频轨道对象。
localAudioTrack: null,
localVideoTrack: null,
};

const options = {
// 替换成你自己项目的 App ID。
appId: "<YOUR APP ID>",
// 传入目标频道名。
channel: "demo_channel_name",
// 如果你的项目开启了 App 证书进行 Token 鉴权,这里填写生成的 Token 值。
token: null,
};

async function startBasicCall() {
/**
* 接下来的代码写在这里。
*/
}

startBasicCall();
```

### 1.创建本地客户端

```js
rtc.client = AgoraRTC.createClient({ mode: "rtc", codec: "h264" });
```

调用 `createClient` 方法创建本地客户端对象。需注意 `mode``codec` 这两个参数的设置:
- `mode` 用于设置[频道场景](https://docs.agora.io/cn/Agora%20Platform/terms?platform=All%20Platforms#channel-profile)。Agora Web SDK NG 会根据使用场景的不同实行不同的优化策略。
- 一对一或多人通话中,建议设为 `"rtc"`,使用通信场景。
- 互动直播中,建议设为 `"live"`,使用直播场景。
- `codec` 用于设置浏览器使用的编解码格式。如果你需要使用 Safari 12.1 及之前版本,将该参数设为 `"h264"`;其他情况我们推荐使用 `"vp8"`

### 2.加入目标频道

```js
const uid = await rtc.client.join(options.appId, options.channel, options.token, null);
```

调用 `join` 加入目标频道。该方法返回一个 `Promise`,当返回 `resolve` 时表示加入频道成功,返回 `reject` 时表示加入频道出现错误。我们可以利用 `async/await` 极大地简化我们的代码。

调用 `join` 方法时你需要注意以下参数:
- `appid`: 你的 App ID。详见[前提条件](setup.md#前提条件)
- `channel`: 频道名,长度在 64 字节以内的字符串。在我们的示例项目中,`channel` 的值设为 `demo_channel_name`
- `token`: (可选)如果你的 Agora 项目开启了 App 证书,你需要在该参数中传入一个 Token,详见[使用 Token](https://docs.agora.io/cn/Agora%20Platform/token?platform=All%20Platforms#%E4%BD%BF%E7%94%A8-token)
- 在测试环境,我们推荐使用控制台生成临时 Token,详见 [获取临时 Token](https://docs.agora.io/cn/Agora%20Platform/token?platform=All%20Platforms%23get-a-temporary-token#%E8%8E%B7%E5%8F%96%E4%B8%B4%E6%97%B6-token)
- 在生产环境,我们推荐你在自己的服务端生成 Token,详见 [生成 Token](https://docs.agora.io/cn/Interactive%20Broadcast/token_server)
> 在我们的示例项目中,为了叙述方便,没有开启 App 证书,所以不需要校验 Token,`token` 的值为 `null`。如果你启用了 App 证书,请确保上面传入的 `channel` 值和生成 Token 时传入的 `channel` 值保持一致。
- `uid`:用户 ID,频道内每个用户的 UID 必须是唯一的。你可以填 `null`,Agora 会自动分配一个 UID 并在 `join` 的结果中返回。

更多的 API 介绍和注意事项请参考 [AgoraRTCClient.join](/api/cn/interfaces/iagorartcclient.html#join) 接口中的参数描述。

### 3.创建并发布本地音视频轨道

```js
// 通过麦克风采集的音频创建本地音频轨道对象。
rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
// 通过摄像头采集的视频创建本地视频轨道对象。
rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
// 将这些音视频轨道对象发布到频道中。
await rtc.client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);

console.log("publish success!");
```

我们先调用 `createMicrophoneAudioTrack` 通过麦克风采集的音频创建本地音频轨道对象,调用 `createCameraVideoTrack` 通过摄像头采集的视频创建本地视频轨道对象;然后调用 `publish` 方法,将这些本地音视频轨道对象当作参数即可将音视频发布到频道中。

> - 以上方法都会返回 `Promise``resolve` 时代表成功,`reject` 时代表失败。我们使用 `async/await` 来让代码逻辑更清晰。
> - 由于加入频道和创建本地音视频轨道没有依赖关系,你可以利用 `Promise.all` 同时执行这些异步操作。
详细的参数设置(如采集设备和编码参数)请参考相关 API 文档:
- [createMicrophoneAudioTrack](/api/cn/interfaces/iagorartc.html#createmicrophoneaudiotrack)
- [createCameraVideoTrack](/api/cn/interfaces/iagorartc.html#createcameravideotrack)
- [publish](/api/cn/interfaces/iagorartcclient.html#publish)

### 4.订阅远端用户
当远端用户发布音视频轨道时,SDK 会触发 `client.on("user-published")` 事件。我们需要通过 `client.on` 监听该事件并在回调中订阅新加入的远端用户。

> 我们建议**在创建客户端对象之后立即监听事件**,以避免错过任何事件。放在这里介绍是因为叙述顺序。
`createClient` 后下一行插入以下代码,监听 `client.on("user-published")` 事件,当有远端用户发布时开始订阅,并在订阅后自动播放远端音视频轨道对象。

```js
rtc.client.on("user-published", async (user, mediaType) => {
// 开始订阅远端用户。
await rtc.client.subscribe(user);
console.log("subscribe success");

// 表示本次订阅的是视频。
if (mediaType === "video") {
// 订阅完成后,从 `user` 中获取远端视频轨道对象。
const remoteVideoTrack = user.videoTrack;
// 动态插入一个 DIV 节点作为播放远端视频轨道的容器。
const playerContainer = document.createElement("div");
// 给这个 DIV 节点指定一个 ID,这里指定的是远端用户的 UID。
playerContainer.id = user.uid.toString();
playerContainer.style.width = "640px";
playerContainer.style.height = "480px";
document.body.append(playerContainer);

// 订阅完成,播放远端音视频。
// 传入 DIV 节点,让 SDK 在这个节点下创建相应的播放器播放远端视频。
remoteVideoTrack.play(playerContainer);

// 也可以只传入该 DIV 节点的 ID。
// remoteVideoTrack.play(playerContainer.id);
}

// 表示本次订阅的是音频。
if (mediaType === "audio") {
// 订阅完成后,从 `user` 中获取远端音频轨道对象。
const remoteAudioTrack = user.audioTrack;
// 播放音频因为不会有画面,不需要提供 DOM 元素的信息。
remoteAudioTrack.play();
}
});
```

你需要注意 `user-published` 事件的第二个参数 `mediaType`, 代表远端用户当前发布的媒体类型:
- `audio`: 远端用户发布了音频轨道。
- `video`: 远端用户发布了视频轨道。

当远端用户取消发布或离开频道时,SDK 会触发 `client.on("user-unpublished")` 事件。此时我们需要销毁刚刚动态创建的 DIV 节点。

在刚刚监听 `client.on("user-published")` 事件的代码下一行插入以下代码,监听 `client.on("user-unpublished")` 事件。

```js
rtc.client.on("user-unpublished", (user, mediaType) => {
if (mediaType === "video") {
// 获取刚刚动态创建的 DIV 节点。
const playerContainer = document.getElementById(user.uid.toString());
// 销毁这个节点。
playerContainer.remove();
}
});
```

### 5.离开频道
通过以下步骤离开频道:
1. 销毁创建的本地音视频轨道,解除网页对摄像头和麦克风的访问。
2. 手动销毁之前动态创建的 DIV 节点。
3. 调用 `leave` 离开频道。

```js
async function leaveCall() {
// 销毁本地音视频轨道。
rtc.localAudioTrack.close();
rtc.localVideoTrack.close();

// 遍历远端用户。
rtc.client.remoteUsers.forEach(user => {
// 销毁动态创建的 DIV 节点。
const playerContainer = document.getElementById(user.uid);
playerContainer && playerContainer.remove();
});

// 离开频道。
await rtc.client.leave();
}
```

> 在不同的产品设计中,离开频道可以既不销毁本地流,也不销毁动态创建的 DIV 节点。这些操作不是必须的,根据您自己的情况调整代码。
## Demo 体验

我们提供了一个简单的演示页面,完成了上述的步骤。你可以访问这个[地址](/demo/basicVideoCall/index.html)在线体验。
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,6 @@ Agora Web SDK NG 支持获取以下统计数据来检测通话质量:

在开始前,请确保已在你的项目中实现基本的实时音视频功能。详见[实现音视频通话](basic_call.md)

### 获取当前会话的统计数据
调用 [AgoraRTCClient.getRTCStats](/api/cn/interfaces/iagorartcclient.html#getrtcstats) 方法获取与当前会话相关的统计数据。数据说明详见 [AgoraRTCStats](/api/cn/interfaces/agorartcstats.html)

以下示例代码中的 `client` 是指通过 `AgoraRTC.createClient` 创建的本地客户端对象。
```js
const stats = client.getRTCStats();
```

### 获取本地音视频轨道的统计数据
调用 [LocalAudioTrack.getStats](/api/cn/interfaces/ilocalaudiotrack.html#getstats)[LocalVideoTrack.getStats](/api/cn/interfaces/ilocalvideotrack.html#getstats) 方法获取本地发布的音频轨道和视频轨道的统计数据,数据说明详见 [LocalAudioTrackStats](/api/cn/interfaces/localaudiotrackstats.html)[LocalVideoTrackStats](/api/cn/interfaces/localvideotrackstats.html)

```js
const audioTrackStats = localAudioTrack.getStats();
const videoTrackStats = localVideoTrack.getStats();
```

### 获取远端音视频轨道的统计数据
调用 [RemoteAudioTrack.getStats](/api/cn/interfaces/iremoteaudiotrack.html#getstats)[RemoteVideoTrack.getStats](/api/cn/interfaces/iremotevideotrack.html#getstats) 方法获取订阅的远端音频轨道和视频轨道的统计数据,数据说明详见 [RemoteAudioTrackStats](/api/cn/interfaces/remoteaudiotrackstats.html)[RemoteVideoTrackStats](/api/cn/interfaces/remotevideotrackstats.html)

```js
const audioTrackStats = remoteAudioTrack.getStats();
const videoTrackStats = remoteVideoTrack.getStats();
```

### 获取本地用户的上下行网络质量相关的统计数据
本地用户加入频道后,SDK 通过 `AgoraRTCClient.on` 中的 [`network-quality`](/api/cn/interfaces/iagorartcclient.html#event_network_quality) 回调向 app 报告本地用户的上下行网络质量。该回调每 2 秒触发,返回的参数包括:
- `downlinkNetworkQuality`:下行网络质量打分。
Expand All @@ -66,6 +42,32 @@ client.on("network-quality", (stats) => {
});
```

> 我们推荐您使用此 API 来展示本地用户的网络状态
### 获取当前会话的统计数据
调用 [AgoraRTCClient.getRTCStats](/api/cn/interfaces/iagorartcclient.html#getrtcstats) 方法获取与当前会话相关的统计数据。数据说明详见 [AgoraRTCStats](/api/cn/interfaces/agorartcstats.html)

以下示例代码中的 `client` 是指通过 `AgoraRTC.createClient` 创建的本地客户端对象。
```js
const stats = client.getRTCStats();
```

### 获取本地音视频轨道的统计数据
调用 [LocalAudioTrack.getStats](/api/cn/interfaces/ilocalaudiotrack.html#getstats)[LocalVideoTrack.getStats](/api/cn/interfaces/ilocalvideotrack.html#getstats) 方法获取本地发布的音频轨道和视频轨道的统计数据,数据说明详见 [LocalAudioTrackStats](/api/cn/interfaces/localaudiotrackstats.html)[LocalVideoTrackStats](/api/cn/interfaces/localvideotrackstats.html)

```js
const audioTrackStats = localAudioTrack.getStats();
const videoTrackStats = localVideoTrack.getStats();
```

### 获取远端音视频轨道的统计数据
调用 [RemoteAudioTrack.getStats](/api/cn/interfaces/iremoteaudiotrack.html#getstats)[RemoteVideoTrack.getStats](/api/cn/interfaces/iremotevideotrack.html#getstats) 方法获取订阅的远端音频轨道和视频轨道的统计数据,数据说明详见 [RemoteAudioTrackStats](/api/cn/interfaces/remoteaudiotrackstats.html)[RemoteVideoTrackStats](/api/cn/interfaces/remotevideotrackstats.html)

```js
const audioTrackStats = remoteAudioTrack.getStats();
const videoTrackStats = remoteVideoTrack.getStats();
```

### 关注频道内的异常事件
Agora Web SDK NG 通过 `AgoraRTCClient.on` 中的 [`exception`](/api/cn/interfaces/iagorartcclient.html#event_exception) 回调通知 App 频道内的异常事件。异常事件不是错误,但是往往会引起通话质量问题。发生异常事件后,如果恢复正常,也会收到该回调。该回调返回:
- `code`:事件码。
Expand All @@ -81,7 +83,7 @@ client.on("exception", function(evt) {

每个异常事件都有对应的恢复事件,详见下表:

![](assets-cn/exception-event.png)
![](assets/exception-event.png)

## 开发注意事项

Expand Down

0 comments on commit 24decb9

Please sign in to comment.