如何为Unity视频通话应用增加云录制

cloud-recording-for-unity-video-chat-featured

本次我们将向你展示如何调用Agora Cloud Recording API来处理Unity应用的任务。你需要熟悉Unity中简单的视频聊天app的基本设置。如果不熟悉,你可以按照Unity快速实现视频通话的教程进行操作,这会让你在30分钟内做好准备。我们进一步扩展了使用自定义服务器控制云录制的逻辑。

要求

  1. 克隆快速入门仓库
  2. 注册声网Agora开发者账户填写快速入门项目上的依赖项,例如获取Agora App ID。
  3. 设置可用的Amazon S3 Bucket。确认可以通过脚本将文件上传到该Bucket中。
  4. 具有基本的服务器端编码知识和环境。

架构

我们将创建一个简单的客户端服务器系统,以模拟该功能的常见用法。这是图1中展示的部分:

  • Unity App客户端1: 命令客户端,它控制视频录制的开始和停止
  • Unity App客户端2: 与客户端1聊天的普通客户端
  • App Server: 存储密钥,从客户端1接收命令并对SD-RTN后端进行RESTFul API调用的受信服务器
  • SD-RTN后端: 传输视频的Agora网络(软件定义实时网络)
  • Amazon S3 Bucket: 拥有视频上传的API的云存储

cloud-recording-for-unity-1
图1:项目架构

注意: 从理论上讲,我们可以从此体系结构中省略应用服务器,并直接调用密钥和RESTFul API到客户端中。但这不是最佳实践。

项目概况

该项目包括三个主要步骤:

  1. 环境: 这涉及在你的Agora帐户上启用该功能以及设置客户端服务器和S3帐户。
  2. 服务器: 代码是用PHP编写的。
  3. 客户端: 在基本视频聊天项目上构建的Unity应用程序。

环境设定

首先,熟悉云端录制上的背景说明。按照“快速入门”部分中有关如何从你的Agora开发人员帐户控制台启用该服务的步骤进行操作。你需要从控制台获得一个 客户 ID 和一个 客户密钥 。从基本的视频聊天项目中添加设置,到目前为止,你应该已经拥有以下Token:

  • AppID: 使用新项目创建。我选择在本教程中不使用证书。
  • App令牌: 仅在你为App ID启用证书时使用。
  • 客户 ID 按“添加密钥”获得一个ID(图2)。
  • 客户密钥 获取客户ID后,控制台会生成一个供下载的密钥令牌。


图2:Agora RESTful控制台

Amazon S3凭证

你需要以下信息来进行云录制配置:

  • Bucket名称: 在我的图3示例中名为“ agoracdn”。
  • 区域: 由于我的 bucket位于“ us-west-1”中,因此根据云端录制RESTful API将其映射到“ 2” 。
  • 用户访问密钥: 从AWS IAM的 用户 下获取此 密钥 (图4)。
  • 用户密钥: 从AWS IAM的“ 用户” 下获取此 密钥


图3:S3管理控制台


图4:IAM管理控制台

服务器环境

你使用的应该是你最熟悉的服务器框架。我从MacBook在本地主机上运行一个快速的PHP服务器。我使用以下命令从我的PHP源代码目录启动服务器:

$ php -S localhost:8000

有关更多信息,例如如何在Windows计算机上执行相同操作,请查看PHP手册页

服务器部署

我们服务器的主要任务是将必要的凭据密钥与客户端分离开,并回调RESTful API到Agora SD-RTN后端。在云录制快速入门文档显示了它的生命周期以下基本步骤:

  1. 获取
  2. 开始
  3. 查询
  4. 停止

这四个步骤映射到在我们的测试服务器中运行的四个PHP脚本。他们将共享我们从以上的“环境设置”步骤中收集的配置。

配置

这是 config.php 的代码。你需要在空白中填写凭证令牌,并设置Amazon S3 bucket的区域号。该脚本将“ 客户ID” 和“ 客户密钥 令牌组合成一个“授权密钥” (AuthSecret)这 将在整个API调用中使用。你应该为 RecUID (录制用户ID)创建一个整数字符串,此ID与客户的用户ID不同。

<?php

// Agora 
$AppID = "";
$CustomerID="";
$CustomerSecret="";
$AuthSecret = base64_encode("$CustomerID:$CustomerSecret");

// You define
$RecUID = "889988";

// Amazaon S3
$S3Region = 2;
$S3Bucket = "";
$S3AccessKey = "";
$S3SecretKey = "";

获取

Aquire步骤初始化对Agora SD-RTN的云录制请求。在返回值中,RTN提供了 resourceId 。频道名是从客户端的POST正文中传递的。作为结果,resourceId被发送到客户端,客户端应在其内存中保留该ID,以进行下一步。


image

开始

获取resourceId之后,可以告诉SD-RTN录制何时开始。SD-RTN将.ts格式的视频数据块发送到S3 bucket。在POST体中从客户端传输 resourceId频道名 后,如果调用成功,则应返回相同的 resourceIdsid (会话ID)。


image

查询

知道录制是否在进行,或是由于AWS身份验证问题会导致启动失败,这两项都很重要。查询命令使用存储的resourceId和sid检查当前状态。服务器以文件列表(m3u8)的当前视频名称和其他信息作为响应。

image

停止

当你决定完成录制时,调用“停止”以完成云录制会话。

注意: 如果在启用证书的情况下设置Agora项目,则需要在Acquire、Start、Stop和Query API调用中将令牌(Token)字段添加到CURLOPT_POSTFIELDS中。由于我的项目是空的,因此我从列表中删除了该字段。

检查点

至此,服务器代码和配置已完成。你可以在创建客户端代码之前手动测试录制。为此,只需手动分配必要的值,而不是从POST主体获取值。

如果你想了解有关RESTful调用的更多信息,可以使用Agora-RESTful-Service项目在Postman应用程序上测试云录制。实际上,我在上面的PHP代码中使用的脚本和JSON主体均受Postman app的启发。你可为所选的框架和语言快速创建相应的代码。见图5和6。

图5:获取代码


图6:使用任意语言

Unity客户端

如“体系结构”部分所述,有两个客户端。客户端1是控制录制开始和停止的命令客户端,客户端2是普通的聊天客户端。原始VideoChat项目适用于客户端2。我们使用新功能更新了该项目,以支持命令客​​户端。

命令功能是MVC设计模式的一个很好的示例应用程序。我们将为模型、视图和控制器编写Unity C#代码。

模型

通过观察SD-RTN返回的JSON输出,我们发现以下示例结构涵盖了Acquire、Start、Stop和Query的响应主体:

{“ resourceId”:“ xxxx”,“ sid”:“ yyy”,“ serverResponse”:{“ status”:5,“ fileList”:“ zzzz.m3u8”,“ fileListMode”:“ string”,“ sliceStartTime”: 160

6357122528}}

将其转换为C#类,我们实现了以下内容:

视图

我们对视频聊天演示场景进行更新:

  1. 在视图区域的左下方添加一个“开始/停止”按钮。将其命名为“ RecordButton”。将文本设置为显示“开始”。我们修改文本以在控制器逻辑中显示“停止”。
  2. 在“开始/停止”按钮下方添加一个查询按钮。使RecordButton作为其在层次结构中的父级。

cloud-recording-for-unity-7
图7:云录制命令客户端

控制器

CloudRecordController 类响应了该按钮事件并封装联网逻辑以驱动云录制。这是类结构自上而下的概述:

cloud-recording-for-unity-8
图8:类结构

Fields

  • ServerURL
  • recordButton
  • queryButton

Properties

  • ChannelName: 由主控制器 (VideoChat.cs)设置
  • ResourceId: 从服务器消息获取,
  • SID: 从服务器消息中获取,
  • IsRecording: 指示是否正在进行录制。

UI控件

HandleStartStop(): 响应 RecordButton 单击并在两种状态之间切换。仅在用户加入频道后,“记录按钮”才可见,并显示为“开始”按钮。当用户点击“ 开始” 按钮时,客户端首先将“获取”命令发送到服务器。如果 Acquire 成功,则Start在响应处理程序中自动响应为 Acquire 。“ 开始” 按钮变为“ 停止” 按钮。该 停止 按钮在用户点击后停止记录。

HandleQuery(): 响应 QueryButton 单击。输出打印到控制台。

RestoreRecordState(): 帮助维护两个Unity客户端会话之间的状态。如果正在进行录制,但用户退出了,则“开始”状态将保存在设备的永久内存 (PlayerPrefs)中 。在主对象的“ Awake” 步骤调用此函数。

SetRecordUI(): 更改“开始”状态和“停止”状态的UI外观。

服务器交互

客户端通过前面定义的四个API调用与服务器进行交互。不难发现,有四个API调用程序和四个用于获取、启动、停止和查询的匹配服务器响应处理程序。

这四个函数对调用和处理程序使用相同的逻辑流。我们使用 UnityWebRequest 类打包和发送POST请求,并使用为 CloudRecordResponseModel 定义的模型解析结果。最后,调用处理程序的回调以完成处理。图9显示了 _Start 函数的示例。


图9:启动功能

_Start() 在协程中与Unity中的Main线程分开运行,因此网络调用不会阻止UI显示的执行。

CloudRecordController类 的完整代码清单





image

整合

现在,我们已经定义了所有的MVC组件,现在我们需要将这些进行整合。我们需要一个游戏对象来托管 CloudRecordController 。我们只需将它作为一个额外的组件添加到 RecordButton中

首先,返回到Unity Editor,并将 CloudRecordController.cs 脚本拖到 RecordButton 。其次,将 RecordButtonQueryButton 分配给它们的字段。第三,在“服务器URL”字段中输入以下URL:

http://localhost:8000/

你的检查器应如下所示:


图10:作为控制器的录制按钮

我们更新了主控制器逻辑以链接到 CloudRecordController

  1. 更新 AgoraTest.cs 脚本 CloudRecordingObject 添加一个新的序列化字段。(见图11)。
  2. Start() 方法中,隐藏 CloudRecordingObject (见图11)。

cloud-recording-for-unity-11
图11:Agora Test Class中的新代码

3.在 OnJoinChannelSuccessHandler() 方法中,更新代码以将频道信息传递给 CloudRecordController (请参见图12)。


图12:通道名称

4.在Unity Editor中,将 RecordButton 拖放到GameController内的 AgoraTest CloudRecordingObject 字段中(参见图13)。

cloud-recording-unity-13
图13:链接到录制对象

测试

首先,进入终端并输入php命令来启动服务器,如图14所示。

cloud-recording-for-unity-14
图14:启动服务器

从Unity编辑器运行项目,并按以下顺序执行:

  1. 加入
  2. 开始
  3. 查询
  4. 停止
  5. 离开

完成后,转到AWS S3帐户检查文件。你应该找到上传的.ts文件的列表。这是我刚刚做的快速测试:

%E6%9C%AA%E5%91%BD%E5%90%8D_%E5%89%AF%E6%9C%AC
图15:样本运行

结论

这个项目有点复杂,需要设置各种不同的配置。感谢关注,完整的项目可以在声网社区Github仓库找到。

原文作者 Rick Cheng
原文链接 https://www.agora.io/en/blog/cloud-recording-for-unity-video-chat/

推荐阅读
相关专栏
SDK 教程
164 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。