使用 Java SDK 开始云端录制
本文向新手介绍如何使用声网 Java SDK 开始第一次云端录制。
Java SDK 旨在帮助开发者更轻松集成声网 RESTful API。该 SDK 具有如下特性:
- 简化通信流畅:通过封装 RESTful API 的请求和响应处理,让你与 RESTful API 的通信更加简单。
- 保障可用性:遇到 DNS 解析失败、网络错误、请求超时等网络问题时,会自动切换到最佳域名,确保 REST 服务的可用性。
- API 易用性:提供简洁易懂的 API,让你能轻松实现开启云端录制、停止云端录制等常用功能。
- 其他优势:基于 Java 语言编写,具有高效性、并发性、可扩展性。
前提条件
开始前请确保你的本地开发环境满足如下条件:
-
Java 1.8 或以上。
-
参考开通服务在声网控制台开通云端录制,并复制保存 App ID、临时 Token、客户 ID 和客户密钥。
注意临时 Token 的有效期是 24 小时。Token 过期会导致加入频道失败。
-
云端录制文件需要上传到第三方云存储。开始录制前,请开通第三方云存储服务,并获取 Bucket、Access Key、Secret Key 以备用。
-
在项目中实现了基础的音视频互动场景。你也可以参考如下步骤,使用声网实时互动 Web Demo 在浏览器中模拟一个基础视频直播场景。
详细步骤- 打开 Web Demo,填入 App ID 和 App 证书完成初始化设置。
- 在左侧选择基础视频直播,然后在右侧的 Channel 栏中填入频道名。注意频道名需要和你生成 Token 时填入的频道名一致。点击 Join as host。
如果模拟成功,你会在 local stream 区域看到你的视频画面。
创建项目并安装 SDK
-
在你的 IDE 中创建一个 Java 项目。以 IntelliJ IDEA 为例,设置你的项目名称、保存路径,并将 Build system 设为 Maven。完成创建后,点击 Create。
-
在项目的
pom.xml
文件中的<dependencies>
区域添加如下行,将 REST Client 的依赖添加到项目中:XML<dependencies>
<dependency>
<groupId>io.agora</groupId>
<artifactId>agora-rest-client-core</artifactId>
<version>0.1.3-BETA</version>
</dependency>
</dependencies>
进行云端录制
本节介绍进行云端录制的极简流程。为方便说明,本节以录制之前模拟的音视频直播为例,并假设录制主播的音频和视频录制到 MP4 文件中。
定义变量
在 Main.java
文件中,添加如下代码,定义或配置关键参数,取值参考前提条件。
public class Main {
// 定义关键参数
private static String appId = "<your_app_id>";
private static String username = "<your_customer_id>";
private static String password = "<your_customer_secret>";
private static String token = "<your_token>";
private static String cname = "testchannel";
private static String uid = "123";
// 配置云存储
private static String accessKey = "<your_storage_access_key>";
private static String secretKey = "<your_storage_secret_key>";
private static Integer region = 1;
private static String bucket = "<your_storage_bucket_name>";
private static Integer vendor = 2;
}
Vendor: 2
代表使用阿里云,如果你使用其他云存储厂商,请下表进行赋值:
云存储厂商 | Vendor ID |
---|---|
Amazon S3 | 1 |
阿里云 | 2 |
腾讯云 | 3 |
Microsoft Azure | 5 |
谷歌云 | 6 |
华为云 | 7 |
百度智能云 | 8 |
创建并初始化 Client
在 main
方法中,添加如下代码,创建并初始化 Client。
Credential basicAuthCredential = new BasicAuthCredential(username, password);
// 初始化 AgoraService
AgoraService agoraService = new AgoraService(
AgoraProperty.builder()
.appId(appId)
.credential(basicAuthCredential)
// Specify the region where the server is located.
// Optional values are CN, NA, EU, AP, and the client will automatically
// switch to use the best domain name according to the configured region
.regionArea(RegionArea.CNRegionArea)
.build()
);
申请录制服务器资源
调用 acquire
申请录制服务器资源。
AcquireResourceRes acquireResourceRes;
// 调用 acquire 申请
try {
acquireResourceRes = agoraService.cloudRecording()
.mixScenario()
.acquire(cname, uid, AcquireMixRecordingResourceClientReq.builder()
.build())
.block();
} catch (AgoraException e) {
System.out.printf("agora error:%s", e.getMessage());
return;
} catch (Exception e) {
System.out.printf("unknown error:%s", e.getMessage());
return;
}
// Check if the response is null
if (acquireResourceRes == null || acquireResourceRes.getResourceId() == null) {
System.out.println("failed to get resource");
return;
}
开始录制
获取资源后,调用 start
开始录制。
// 设置云存储
StartResourceReq.StorageConfig storageConfig = StartResourceReq.StorageConfig.builder()
.accessKey(accessKey)
.secretKey(secretKey)
.bucket(bucket)
.vendor(vendor)
.region(region)
// 设置录制生成文件的存储路径
.fileNamePrefix(List.of("quickstart"))
.build();
// 配置录制选项
StartMixRecordingResourceClientReq startResourceReq = StartMixRecordingResourceClientReq.builder()
.token(token)
.recordingConfig(StartResourceReq.RecordingConfig.builder()
.channelType(1)
.build())
.recordingFileConfig(StartResourceReq.RecordingFileConfig.builder()
.avFileType(Arrays.asList("hls", "mp4"))
.build())
.storageConfig(storageConfig)
.build();
StartResourceRes startResourceRes;
// 调用 start 开始
try {
startResourceRes = agoraService.cloudRecording()
.mixScenario()
.start(cname, uid,
acquireResourceRes.getResourceId(),
startResourceReq)
.block();
} catch (AgoraException e) {
System.out.printf("agora error:%s", e.getMessage());
return;
} catch (Exception e) {
System.out.printf("unknown error:%s", e.getMessage());
return;
}
// Check if the response is null
if (startResourceRes == null || startResourceRes.getSid() == null) {
System.out.println("failed to start resource");
return;
}
System.out.printf("sid:%s", startResourceRes.getSid());
System.out.println("start resource success");
Thread.sleep(10000);
停止录制
完成录制后,调用 stop
结束录制。
StopResourceRes stopResourceRes;
// 调用 stop 停止
try {
stopResourceRes = agoraService.cloudRecording()
.mixScenario()
.stop(cname, uid, startResourceRes.getResourceId(), startResourceRes.getSid(),
true)
.block();
} catch (AgoraException e) {
System.out.printf("agora error:%s", e.getMessage());
return;
} catch (Exception e) {
System.out.printf("unknown error:%s", e.getMessage());
return;
}
// Check if the response is null
if (stopResourceRes == null || stopResourceRes.getSid() == null) {
System.out.println("failed to stop resource");
} else {
System.out.println("stop resource success");
}
完整示例代码
Main.java
文件中完整代码如下,你可自行比对:
public class Main {
// 定义关键参数
private static String appId = "<your_app_id>";
private static String username = "<your_customer_id>";
private static String password = "<your_customer_secret>";
private static String token = "<your_token>";
private static String cname = "testchannel";
private static String uid = "123";
// 配置云存储
private static String accessKey = "your_storage_access_key";
private static String secretKey = "your_storage_secret_key";
private static Integer region = 1;
private static String bucket = "<your_storage_bucket_name>";
private static Integer vendor = 2;
public static void main(String[] args) throws Exception {
Credential basicAuthCredential = new BasicAuthCredential(username, password);
// 初始化 AgoraService
AgoraService agoraService = new AgoraService(
AgoraProperty.builder()
.appId(appId)
.credential(basicAuthCredential)
// Specify the region where the server is located.
// Optional values are CN, NA, EU, AP, and the client will automatically
// switch to use the best domain name according to the configured region
.regionArea(RegionArea.CNRegionArea)
.build()
);
AcquireResourceRes acquireResourceRes;
// 申请录制服务器资源
try {
acquireResourceRes = agoraService.cloudRecording()
.mixScenario()
.acquire(cname, uid, AcquireMixRecordingResourceClientReq.builder()
.build())
.block();
} catch (AgoraException e) {
System.out.printf("agora error:%s", e.getMessage());
return;
} catch (Exception e) {
System.out.printf("unknown error:%s", e.getMessage());
return;
}
// Check if the response is null
if (acquireResourceRes == null || acquireResourceRes.getResourceId() == null) {
System.out.println("failed to get resource");
return;
}
System.out.printf("resourceId:%s", acquireResourceRes.getResourceId());
System.out.println("acquire resource success");
// 配置云存储
StartResourceReq.StorageConfig storageConfig = StartResourceReq.StorageConfig.builder()
.accessKey(accessKey)
.secretKey(secretKey)
.bucket(bucket)
.vendor(vendor)
.region(region)
// 设置录制生成文件的存储路径
.fileNamePrefix(List.of("quickstart"))
.build();
// 定义录制选项
StartMixRecordingResourceClientReq startResourceReq = StartMixRecordingResourceClientReq.builder()
.token(token)
.recordingConfig(StartResourceReq.RecordingConfig.builder()
.channelType(1)
.build())
.recordingFileConfig(StartResourceReq.RecordingFileConfig.builder()
.avFileType(Arrays.asList("hls", "mp4"))
.build())
.storageConfig(storageConfig)
.build();
StartResourceRes startResourceRes;
// 开始录制
try {
startResourceRes = agoraService.cloudRecording()
.mixScenario()
.start(cname, uid,
acquireResourceRes.getResourceId(),
startResourceReq)
.block();
} catch (AgoraException e) {
System.out.printf("agora error:%s", e.getMessage());
return;
} catch (Exception e) {
System.out.printf("unknown error:%s", e.getMessage());
return;
}
// Check if the response is null
if (startResourceRes == null || startResourceRes.getSid() == null) {
System.out.println("failed to start resource");
return;
}
System.out.printf("sid:%s", startResourceRes.getSid());
System.out.println("start resource success");
Thread.sleep(10000);
QueryMixHLSAndMP4RecordingResourceRes queryResourceRes;
// 查询录制状态
try {
queryResourceRes = agoraService.cloudRecording()
.mixScenario()
.queryHLSAndMP4(startResourceRes.getResourceId(), startResourceRes.getSid())
.block();
} catch (AgoraException e) {
System.out.printf("agora error:%s", e.getMessage());
return;
} catch (Exception e) {
System.out.printf("unknown error:%s", e.getMessage());
return;
}
if (queryResourceRes == null || queryResourceRes.getServerResponse() == null) {
System.out.println("failed to query resource");
return;
}
System.out.println("query resource success");
Thread.sleep(3000);
StopResourceRes stopResourceRes;
// 停止录制
try {
stopResourceRes = agoraService.cloudRecording()
.mixScenario()
.stop(cname, uid, startResourceRes.getResourceId(), startResourceRes.getSid(),
true)
.block();
} catch (AgoraException e) {
System.out.printf("agora error:%s", e.getMessage());
return;
} catch (Exception e) {
System.out.printf("unknown error:%s", e.getMessage());
return;
}
// Check if the response is null
if (stopResourceRes == null || stopResourceRes.getSid() == null) {
System.out.println("failed to stop resource");
} else {
System.out.println("stop resource success");
}
}
}
查看录制文件
参考第三方云存储官方文档操作,查看云存储中的文件。根据 start
方法中 storageconfig.fileNamePrefix
参数的设置,录制生成文件位于 quickstart
目录下。如下截图以阿里云为例:
录制过程中生成了 .m3u8
、.ts
和 mp4
文件。最终 quickstart
文件夹内包含如下:
.
├── <sid>_testchannel.m3u8
├── <sid>_testchannel_0.mp4
└── <sid>_testchannel_20241119070642248.ts
根据你在 start
方法中设置的录制时间,云存储中可能会有多个 .ts 文件。录制文件介绍请参考录制文件命名和切片规则。
进阶设置
本文提供的示例代码仅为快速上手时使用。在实际业务中,你需要根据实际业务场景修改请求参数。如下示例代码展示了录制直播频道中所有的音视频流,且输出的视频流需要转码的参数配置:
// 配置录制选项
StartMixRecordingResourceClientReq startResourceReq = StartMixRecordingResourceClientReq.builder()
.token(token)
.recordingConfig(StartResourceReq.RecordingConfig.builder()
.channelType(1)
.streamTypes(2)
.maxIdleTime(30)
.audioProfile(2)
.transcodingConfig(StartResourceReq.TranscodingConfig.builder()
.width(640)
.height(480)
.fps(15)
.bitrate(800)
.mixedVideoLayout(0)
.backgroundColor("#000000")
.build())
.subscribeAudioUIDs(Collections.singletonList("#allstream#"))
.subscribeVideoUIDs(Collections.singletonList("#allstream#"))
.build())
.recordingFileConfig(StartResourceReq.RecordingFileConfig.builder()
.avFileType(Arrays.asList("hls", "mp4"))
.build())
.storageConfig(storageConfig)
.build();
云端录制支持设置的所有参数请参考 API 文档。
参考信息
示例项目
完成快速开始后,你可以体验更多云端录制示例: