本次我们将向你展示如何调用Agora Cloud Recording API来处理Unity应用的任务。你需要熟悉Unity中简单的视频聊天app的基本设置。如果不熟悉,你可以按照Unity快速实现视频通话的教程进行操作,这会让你在30分钟内做好准备。我们进一步扩展了使用自定义服务器控制云录制的逻辑。
要求
- 克隆快速入门仓库。
- 注册声网Agora开发者账户填写快速入门项目上的依赖项,例如获取Agora App ID。
- 设置可用的Amazon S3 Bucket。确认可以通过脚本将文件上传到该Bucket中。
- 具有基本的服务器端编码知识和环境。
架构
我们将创建一个简单的客户端服务器系统,以模拟该功能的常见用法。这是图1中展示的部分:
- Unity App客户端1: 命令客户端,它控制视频录制的开始和停止
- Unity App客户端2: 与客户端1聊天的普通客户端
- App Server: 存储密钥,从客户端1接收命令并对SD-RTN后端进行RESTFul API调用的受信服务器
- SD-RTN后端: 传输视频的Agora网络(软件定义实时网络)
- Amazon S3 Bucket: 拥有视频上传的API的云存储
图1:项目架构
注意: 从理论上讲,我们可以从此体系结构中省略应用服务器,并直接调用密钥和RESTFul API到客户端中。但这不是最佳实践。
项目概况
该项目包括三个主要步骤:
- 环境: 这涉及在你的Agora帐户上启用该功能以及设置客户端服务器和S3帐户。
- 服务器: 代码是用PHP编写的。
- 客户端: 在基本视频聊天项目上构建的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后端。在云录制快速入门文档显示了它的生命周期以下基本步骤:
- 获取
- 开始
- 查询
- 停止
这四个步骤映射到在我们的测试服务器中运行的四个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,以进行下一步。
开始
获取resourceId之后,可以告诉SD-RTN录制何时开始。SD-RTN将.ts格式的视频数据块发送到S3 bucket。在POST体中从客户端传输 resourceId 和 频道名 后,如果调用成功,则应返回相同的 resourceId 和 sid (会话ID)。
查询
知道录制是否在进行,或是由于AWS身份验证问题会导致启动失败,这两项都很重要。查询命令使用存储的resourceId和sid检查当前状态。服务器以文件列表(m3u8)的当前视频名称和其他信息作为响应。
停止
当你决定完成录制时,调用“停止”以完成云录制会话。
注意: 如果在启用证书的情况下设置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#类,我们实现了以下内容:
视图
我们对视频聊天演示场景进行更新:
- 在视图区域的左下方添加一个“开始/停止”按钮。将其命名为“ RecordButton”。将文本设置为显示“开始”。我们修改文本以在控制器逻辑中显示“停止”。
- 在“开始/停止”按钮下方添加一个查询按钮。使RecordButton作为其在层次结构中的父级。
图7:云录制命令客户端
控制器
CloudRecordController 类响应了该按钮事件并封装联网逻辑以驱动云录制。这是类结构自上而下的概述:
图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类 的完整代码清单 :
整合
现在,我们已经定义了所有的MVC组件,现在我们需要将这些进行整合。我们需要一个游戏对象来托管 CloudRecordController 。我们只需将它作为一个额外的组件添加到 RecordButton中 。
首先,返回到Unity Editor,并将 CloudRecordController.cs 脚本拖到 RecordButton 。其次,将 RecordButton 和 QueryButton 分配给它们的字段。第三,在“服务器URL”字段中输入以下URL:
你的检查器应如下所示:
图10:作为控制器的录制按钮
我们更新了主控制器逻辑以链接到 CloudRecordController 。
- 更新 AgoraTest.cs 脚本 , 为 CloudRecordingObject 添加一个新的序列化字段。(见图11)。
- 在 Start() 方法中,隐藏 CloudRecordingObject (见图11)。
图11:Agora Test Class中的新代码
3.在 OnJoinChannelSuccessHandler() 方法中,更新代码以将频道信息传递给 CloudRecordController (请参见图12)。
图12:通道名称
4.在Unity Editor中,将 RecordButton 拖放到GameController内的 AgoraTest CloudRecordingObject 字段中(参见图13)。
图13:链接到录制对象
测试
首先,进入终端并输入php命令来启动服务器,如图14所示。
图14:启动服务器
从Unity编辑器运行项目,并按以下顺序执行:
- 加入
- 开始
- 查询
- 停止
- 离开
完成后,转到AWS S3帐户检查文件。你应该找到上传的.ts文件的列表。这是我刚刚做的快速测试:
图15:样本运行
结论
这个项目有点复杂,需要设置各种不同的配置。感谢关注,完整的项目可以在声网社区Github仓库找到。
原文作者 Rick Cheng
原文链接 https://www.agora.io/en/blog/cloud-recording-for-unity-video-chat/