基于 Agora SDK 实现 Web 端的多人视频互动

根据本文指导快速集成 Agora Web SDK 并在你自己的 app 里实现音视频互动直播。

本文会详细介绍如何建立一个简单的项目并使用 Agora Web SDK 实现基础的互动直播。我们建议你阅读本文以快速了解 Agora 的核心方法。

互动直播和实时通话的区别在于,直播频道的用户有角色之分。你可以将角色设置为主播,或者观众,其中主播可以收、发流,观众只能收流。

实现互动直播的步骤如下:

1. 设置角色

互动直播频道用户角色可以是主播或者观众。主播在频道内发布音视频流,观众可订阅流。

2. 获取 Token

当 app 客户端加入频道时,你需要使用 Token 验证用户身份。App 客户端向 app 服务器发送请求,并获取 Token,然后在客户端加入频道时验证用户身份。

3. 加入频道

调用 joinChannel 创建并加入频道。使用同一频道名称的 app 客户端默认加入同一频道。

4. 在频道内发布和订阅音视频

加入频道后,用户角色为主播的 app 客户端可以发布音视频。对于角色为观众的客户端,如果想要发布音视频,可以调用 setClientRole 切换用户角色。

你可以调用 LocalTrackRemoteTrack 对象来发布和订阅频道中的音频和视频轨道。

App 客户端加入频道需要以下信息:

  • App ID:Agora 随机生成的字符串,用于识别你的 app,可在注册声网账号后,从 Agora 控制台获取。
  • 用户 ID:用户的唯一标识。你需要自行设置用户 ID,并确保它在频道内是唯一的。
  • Token:在测试或生产环境中,你的 app 客户端会从你的服务器中获取 Token。为方便快速测试,你也可以获取临时 Token。临时 Token 的有效期为 24 小时。
  • 频道名称:用于标识直播频道的字符串。

Web 浏览器中的互动直播基本工作流程如下:

前提条件

你需要满足以下前提条件:

创建 Web 项目

创建一个名为 agora_web_quickstart 的文件夹。一个 Web 客户端项目至少需包含以下文件:

  • index.html: 用于设计 Web 应用的用户界面。
  • basicLiveStreaming.js: 通过 AgoraRTCClient 实现具体应用逻辑的代码。
  • package.json: 安装并管理项目依赖。你可以通过命令行进入 agora_web_quickstart 目录并运行 npm init 命令来创建 package.json 文件。

实现音视频互动直播

集成 SDK

参考以下步骤通过 npm 将 Agora Web SDK 集成到你的项目中:

  1. package.json 文件的 dependencies 字段中添加 agora-rtc-sdk-ng 及版本号:

{
  "name": "agora_web_quickstart",
  "version": "1.0.0",
  "description": "",
  "main": "basicLiveStreaming.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "agora-rtc-sdk-ng": "latest",
  },
  "author": "",
  "license": "ISC"
}

2. 将以下代码复制到 basicLiveStreaming.js 文件中,在你的项目中导入 AgoraRTC 模块。

import AgoraRTC from "agora-rtc-sdk-ng"

实现一个简单的用户界面

将以下代码复制到 index.html 实现客户端用户界面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Agora Video Web SDK Quickstart</title>
    <!--
      This line is used to refer to the bundle.js file packaged by webpack. A sample webpack configuration is shown in the later step of running your app.
    -->
    <script src="./dist/bundle.js"></script>
</head>
<body>
    <h2 class="left-align">Agora Video Web SDK Quickstart</h2>
        <div class="row">
            <div>
                <button type="button" id="host-join">Join as host</button>
                <button type="button" id="audience-join">Join as audience</button>
                <button type="button" id="leave">Leave</button>
            </div>
        </div>
</body>
</html>

3. 实现音视频互动直播逻辑

参考以下步骤实现音视频互动直播的逻辑:

  1. 调用 createClient 方法创建 AgoraRTCClient 对象。
  2. 调用 setClientRole 方法,将角色 role 设为 "host" (主播)或 "audience"(观众)。主播既可发布轨道,也可订阅轨道;观众不能进行发布操作。
  3. 调用 join 方法加入一个 RTC 频道,你需要在该方法中传入 App ID 、用户 ID、Token、频道名称。
  4. 如果角色为主播,需要先调用 createMicrophoneAudioTrack 通过麦克风采集的音频创建本地音频轨道对象,调用 createCameraVideoTrack 通过摄像头采集的视频创建本地视频轨道对象;然后调用 publish 方法,将这些本地音视频轨道对象当作参数即可将音视频发布到频道中。
  5. 当一个远端用户加入频道并发布音视频轨道时:
    1. 监听 client.on("user-published") 事件。当 SDK 触发该事件时,在这个事件回调函数的参数中你可以获取远端用户 AgoraRTCRemoteUser 对象 。
    2. 调用 subscribe 方法订阅远端用户 AgoraRTCRemoteUser 对象,获取远端用户的远端音频轨道 RemoteAudioTrack 和远端视频轨道 RemoteVideoTrack 对象。
    3. 调用 play 方法播放远端音视频轨道。

下图展示了基础的音视频直播的 API 调用。注意图中的方法是对不同的对象调用的。

将以下代码复制到 basicLiveStreaming.js 文件中,注意将 appIDtoken 替换为你自己的 App ID 和临时 Token

import AgoraRTC from "agora-rtc-sdk-ng"

let rtc = {
    // For the local audio and video tracks.
    localAudioTrack: null,
    localVideoTrack: null,
    client: null
};

let options = {
    // Pass your app ID here.
    appId: "your_app_id",
    // Set the channel name.
    channel: "test",
    // Use a temp token
    token: "your_temp_token",
    // Uid
    uid: 123456
};

async function startBasicLiveStreaming() {

    rtc.client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });

    window.onload = function () {

        document.getElementById("host-join").onclick = async function () {
            rtc.client.setClientRole("host");
            await rtc.client.join(options.appId, options.channel, options.token, options.uid);
            // Create an audio track from the audio sampled by a microphone.
            rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
            // Create a video track from the video captured by a camera.
            rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
            // Publish the local audio and video tracks to the channel.
            await rtc.client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);
            // Dynamically create a container in the form of a DIV element for playing the remote video track.
            const localPlayerContainer = document.createElement("div");
            // Specify the ID of the DIV container. You can use the `uid` of the remote user.
            localPlayerContainer.id = options.uid;
            localPlayerContainer.textContent = "Local user " + options.uid;
            localPlayerContainer.style.width = "640px";
            localPlayerContainer.style.height = "480px";
            document.body.append(localPlayerContainer);

            rtc.localVideoTrack.play(localPlayerContainer);

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

        document.getElementById("audience-join").onclick = async function () {
            rtc.client.setClientRole("audience");
            await rtc.client.join(options.appId, options.channel, options.token, options.uid);
            rtc.client.on("user-published", async (user, mediaType) => {
                // Subscribe to a remote user.
                await rtc.client.subscribe(user, mediaType);
                console.log("subscribe success");

                // If the subscribed track is video.
                if (mediaType === "video") {
                    // Get `RemoteVideoTrack` in the `user` object.
                    const remoteVideoTrack = user.videoTrack;
                    // Dynamically create a container in the form of a DIV element for playing the remote video track.
                    const remotePlayerContainer = document.createElement("div");
                    // Specify the ID of the DIV container. You can use the `uid` of the remote user.
                    remotePlayerContainer.id = user.uid.toString();
                    remotePlayerContainer.textContent = "Remote user " + user.uid.toString();
                    remotePlayerContainer.style.width = "640px";
                    remotePlayerContainer.style.height = "480px";
                    document.body.append(remotePlayerContainer);


                    // Play the remote video track.
                    // Pass the DIV container and the SDK dynamically creates a player in the container for playing the remote video track.
                    remoteVideoTrack.play(remotePlayerContainer);

                    // Or just pass the ID of the DIV container.
                    // remoteVideoTrack.play(playerContainer.id);
                }

                // If the subscribed track is audio.
                if (mediaType === "audio") {
                    // Get `RemoteAudioTrack` in the `user` object.
                    const remoteAudioTrack = user.audioTrack;
                    // Play the audio track. No need to pass any DOM element.
                    remoteAudioTrack.play();
                }
            });

            rtc.client.on("user-unpublished", user => {
                    // Get the dynamically created DIV container.
                    const remotePlayerContainer = document.getElementById(user.uid);
                    // Destroy the container.
                    remotePlayerContainer.remove();
            });
        }

        document.getElementById("leave").onclick = async function () {
            // Close all the local tracks.
            rtc.localAudioTrack.close();
            rtc.localVideoTrack.close();
            // Traverse all remote users.
            rtc.client.remoteUsers.forEach(user => {
                // Destroy the dynamically created DIV containers.
                const playerContainer = document.getElementById(user.uid);
                playerContainer && playerContainer.remove();
            });

            // Leave the channel.
            await rtc.client.leave();
        }
    }

}

startBasicLiveStreaming()

运行项目

本文使用 webpack 打包项目,使用 webpack-dev-server 运行项目。

  1. package.jsondependencies 中添加 webpack-cliwebpack-dev-server 字段中,在 scripts 字段中添加 buildstart:dev 字段。

{
  "name": "agora_web_quickstart",
  "version": "1.0.0",
  "description": "",
  "main": "basicLiveStreaming.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.config.js",
    "start:dev": "webpack serve --open --config webpack.config.js"
 },
  "dependencies": {
    "agora-rtc-sdk-ng": "latest",
    "webpack": "5.28.0",
    "webpack-dev-server": "3.11.2",
    "webpack-cli": "4.5.0"
 },
  "author": "",
  "license": "ISC"
}

2.在项目目录中创建一个名为 webpack.config.js 的文件,将以下代码复制到 webpack.config.js 配置 webpack:

const path = require('path');

module.exports = {
  entry: './basicLiveStreaming.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist'),
  },
  devServer: {
    compress: true,
    port: 9000
  }
};

3.运行下列命令安装依赖:

npm install

4.运行下列命令通过 webpack 编译项目:

# Use webpack to package the project
npm run build

5.通过 webpack-dev-server 运行项目:

npm run start:dev

你的浏览器会自动打开以下页面:

点击 JOIN 加入频道。你还可以将这个在线 Web 应用链接以及你的 Agora App ID 和临时 Token 发给朋友。你和朋友可分别以主播和观众的角色加入同一频道,看看是否能看到对方。

注册声网Agora开发者账号,快速开始。

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值