有奖捉虫:办公协同&微信生态&物联网文档专题 HOT
注意
1. 当录制房间内5分钟没有任何音视频上行,且这5分钟内没有任何白板操作的时候,录制任务将自动停止录制。
2. 当录制任务暂停超过90分钟的时候,录制任务将自动停止录制。
3. 当录制任务开始后,超过24小时没有调用结束录制,录制任务将自动停止录制。
4. 录制结果文件只保存3天,3天后将被删除,建议在使用录制功能前进行 存储桶配置,或在获取到录制结果后自行对录制文件进行转存。

交互流程

实时录制模式

实时录制模式从开始上课到最终进行课堂回放一般经过如下几个交互过程(以配置了事件回调地址为例):



视频生成模式

视频生成模式交互流程与实时录制模式大体一致,区别在于回放需要使用特殊播放器,另外需要视频文件的话,可以选择重新生成视频。



录制任务状态转换

录制任务的生命周期内存在五种状态:
PREPARED - 表示录制任务创建成功,但录制还没有正式开始。
RECORDING - 表示录制任务已经正式开始录制。
PAUSED - 表示录制任务已暂停
STOPPED - 表示录制任务已经停止录制,正在进行录制结果处理。
FINISHED - 表示录制任务已结束
状态转换过程如下:



准备工作

存储桶配置

录制的结果文件(视频文件、录制元数据、消息暂存等)的存储依赖 对象存储 COS 服务,因此在使用录制功能前,请务必先进行 存储桶配置
注意
如果没有进行存储桶配置,则录制服务会将录制结果存储到内部公共桶,且仅保留3天,3天后将被删除。

准备 RecordUserIdRecordUserSig

录制服务需要加入课堂并对课堂的音视频和白板进行录制,因此需要您提供一个录制服务进房时使用的RecordUserId以及RecordUserSig,生成RecordUserIdRecordUserSig的方法请参考 如何计算 UserSig
为了将录制后台的RecordUserId与普通用户进行区分,我们约定RecordUserId的格式必须如下:
tic_record_user_{roomid}_{随机数}
其中,{roomid}为您真实的房间号,假如课堂的音视频房间100241,一个合法的录制RecordUserIdtic_record_user_100241_100。同时您需要提供tic_record_user_100241_100对应的RecordUserSig签名。
注意
1. RecordUserSig签名请设置一个较长的有效期,例如1小时,避免由于签名过期导致录制失败。
2. 如果同一房间内需要多次发起录制,请使用不同的录制RecordUserId,否则录制用户会被强制下线而导致录制失败。

开通实时音视频云端自动录制

开通实时音视频云端录制的目的:
实时录制模式可能会因为不可抗原因导致录制出现异常,如果希望在录制结束后对异常视频进行恢复,请务必在使用实时录制模式前开通实时音视频云端自动录制。
视频生成模式依赖实时音视频的云端录制功能,如果要使用视频生成模式,请务必在使用视频生成模式前开通实时音视频云端自动录制。
配置方法:
1. 登录 实时音视频控制台,在左侧导航栏选择应用管理
2. 单击目标应用所在行的功能配置 ,进入功能配置页卡。如果您还没有创建过应用,可以单击创建应用,填写应用名称,单击确定创建一个新的应用。
3. 单击启动云端录制右侧的

,会弹出云端录制的设置页面。
4. 在弹出的云端录制设置页面中,录制形式选择全局自动录制,录制文件格式选择MP4。


开通实时音视频云端录制的更多设置内容可以参考实时音视频的 实现云端录制与回放 页面。

在客户端发送对时信息(视频生成模式)

注意
1. 此小节仅在使用视频生成模式时需要关注,仅使用实时录制模式可忽略此内容。
2. 如果使用TIC进行白板接入的话,可以忽略此内容。
由于视频生成模式的音视频录制与白板录制是由不同服务录制的,需要业务侧在客户端配合调用实时音视频 SDK 接口定时地将白板对时信息写入到视频帧中,从而保证在回放时播放器能够根据对时信息对多路流进行同步播放,视频生成任务可以根据对时信息对多路流进行混流时保持白板与视频之间的音画同步。
对时信息的定义如下:
{
"syncTime": 1600152855000
}
其中 syncTime 为白板时间,需要通过白板 SDK 提供的接口获取,单位为毫秒(ms)。
要完成对时信息的发送,不同平台的实现方式不一样,下边针对不同平台进行一一说明。
Android
在白板初始化完成后,启动一个定时任务,定时的通过白板 SDK 提供的 getSyncTime 方法获取白板时间,并通过 TRTC SDK 提供的 sendSEIMsg 接口把白板时间添加到视频帧里。
这里以 Handler 实现的定时任务为例,先定义一个 Handler
static class syncTimeHandler extends Handler {
WeakReference<TRTCCloud> mTRTCCloud;
WeakReference<TEduBoardController> mBoard;

syncTimeHandler(TRTCCloud trtcCloud, TEduBoardController board) {
mTRTCCloud = new WeakReference<>(trtcCloud);
mBoard = new WeakReference<>(board);
}

@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);

sendSyncTimeBySEI();
sendEmptyMessageDelayed(0, 5000);
}

private void sendSyncTimeBySEI() {
TRTCCloud trtcCloud = mTRTCCloud.get();
TEduBoardController board = mBoard.get();

if (trtcCloud != null && board != null) {
long time = board.getSyncTime();
if (time != 0) {
String result = "";
JSONObject json = new JSONObject();
try {
json.put("syncTime", time);
result = json.toString();
} catch (Exception e) {
e.printStackTrace();
}
if (!TextUtils.isEmpty(result)) {
trtcCloud.sendSEIMsg(result.getBytes(), 1);
}
}
}
}
}
在白板与 TRTC 实例初始化完成后,通过以上定义的 Handler 来触发定时发送对时信息,代码中的trtcCloud以及board分别为已经初始化完成的 TRTC 实例及白板控制实例,初始化操作可以参考 白板 SDK 集成文档
Handler handler = new syncTimeHandler(trtcCloud, board);
handler.sendEmptyMessage(0);
iOS/Mac
在白板初始化完成后,启动一个定时任务,定时的通过白板 SDK 提供的 getSyncTime 方法获取白板时间,并通过 TRTC SDK 提供的 sendSEIMsg 接口把白板时间添加到视频帧里。
发送对时信息的代码示例如下:
void syncRemoteTime:(TRTCCloud *)trtcCloud board:(TEduBoardController *)board {
// 获取白板时间
uint64_t syncTime = [board getSyncTime];
NSMutableDictionary *dataDic = [NSMutableDictionary dictionary];
[dataDic setObject:[NSNumber numberWithLongLong:syncTime] forKey:@"syncTime"];
NSData *data = [NSJSONSerialization dataWithJSONObject:dataDic options:0 error:nil];
[trtcCloud sendSEIMsg:data repeatCount:1];
}
在白板与 TRTC 实例初始化完成后,启动一个定时任务来实现定时发送对时信息,其中的 trtcCloudboard 分别为已经初始化完成的 TRTC 实例及白板控制实例,初始化操作可以参考 白板 SDK 集成文档
NSTimer *syncTimer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
syncRemoteTime(trtcCloud, board);
}];
在退出的时候记得停止已启动的定时器,避免出现内存泄漏。
if (syncTimer && [syncTimer isValid]) {
[syncTimer invalidate];
syncTimer = nil;
}
Windows
在白板初始化完成后,启动一个定时任务,定时的通过白板 SDK 提供的 GetSyncTime 方法获取白板时间,并通过 TRTC SDK 提供的 sendSEIMsg 接口把白板时间添加到视频帧里。
下边以 C++ 代码为例,代码中的trtcCloud以及board分别为已经初始化完成的 TRTC 实例及白板控制实例,初始化操作可以参考 白板 SDK 集成文档
先实现一个简单的定时器:

#include <thread>

class Timer {
public:
template<typename Function>
inline void setInterval(Function func, int interval) {
stopped_ = false;

std::thread t([=]{
while(true) {
if(stopped_) return;
std::this_thread::sleep_for(std::chrono::milliseconds(interval));
if(stopped_) return;

if(func) {
func();
}
}
});

t.detach();
}

inline void stop() {
stopped_ = true;
}
private:
bool stopped_;
};
最后在白板与 TRTC 实例初始化完成后,启动定时器定时发送对时信息,其中的 trtcCloudboard 分别为已经初始化完成的 TRTC 实例及白板控制实例,初始化操作可以参考 白板 SDK 集成文档
#include <sstream>

Timer t;
t.setInterval([trtcCloud, board]{
std::stringstream ss;
ss << "{\\"syncTime\\":" << board->GetSyncTime() << "}";
auto jsonStr = ss.str();

trtcCloud->sendSEIMsg((uint8_t*)jsonStr.c_str(), (uint32_t)jsonStr.length(), 1);
}, 5000);

Web
web 端的TRTC SDK不提供SendSEIMsg接口,所以需要在进房的时候通过设置BusinessInfo的方法将白板服务校正过的时间戳同步给实时音视频服务的WebRTC后台服务。
在白板初始化完成后,通过白板 SDK 提供的 getSyncTime 方法获取白板时间。
syncTime = this.whiteBoard.getSyncTime()
然后在创建TRTC Client的时候,把syncTime设置到TRTC初始化参数bussinessInfo中,可参考 TRTC SDK 提供的 createClient 接口。
let param = {
mode: 'live',
sdkAppId: {您的 sdkAppID},
userId: {您的用户 ID},
userSig: {对应用户 ID 的 UserSig},
bussinessInfo: JSON.stringify({Str_uc_params:{syncTime: syncTime}})
}

// 创建TRTC Client
this.client = TRTC.createClient(param)

开始录制

在需要进行录制时,例如老师学生都已经准备好开始上课,您可以使用 开始录制 接口开始录制,在请求接口时,需要使用到上一步准备好的RecordUserIdRecordUserSig,当录制开始时,如果您配置了回调地址,您将收到事件为 录制开始 的回调请求通知。
说明
由于网络延迟等因素,发送请求后,实际录制操作将在2s左右后进行。 目前服务端 API 接口只支持区域广州,在调用 API 时,Region参数请填写ap-guangzou。

暂停录制 和 恢复录制(可选)

在上课过程中,如果您不希望录制中间一段内容(例如课间休息),并且想要将暂停前和暂停后的视频放在一个录制任务结果中,您可以使用暂停录制 接口和 恢复录制 接口实现。
说明
由于网络延迟等因素,发送请求后,实际录制操作将在2s左右后进行。 目前服务端 API 接口只支持区域广州,在调用 API 时,Region参数请填写ap-guangzou。

停止录制

在课堂结束或者需要停止录制的时候,您可以使用 停止录制 接口通知录制服务停止当前录制,如果您配置了回调地址,录制视频处理完成后,您将收到事件为 录制停止 的回调请求通知。
说明
由于网络延迟等因素,发送请求后,实际录制操作将在2s左右后进行。 目前服务端 API 接口只支持区域广州,在调用 API 时,Region参数请填写ap-guangzou。

获取录制结果

录制服务提供了两种方式来获取录制结果:
设置录制事件回调地址 通过 控制台 或者 设置回调地址 接口都可以完成设置录制事件回调地址。在录制任务结束后,录制服务会把录制结果回调到已设置好的地址,您可以在收到回调后根据业务需要对录制结果进行记录或者其他操作。
通过 查询录制任务 接口主动查询 在录制过程中或者停止录制后,您都可以使用 查询录制任务 接口来查询录制任务的具体信息。


解析录制任务结果

当您主动查询录制进度时收到 Status 参数值为 "FINISHED" 或者收到录制完成回调时,您可以拿到录制结果(一个 JSON 串),其格式如下:
参数名
类型
描述
RoomId
Integer
房间号
GroupId
String
白板的群组 ID
RecordUserId
String
录制所使用的 UserId
RecordStartTime
Integer
录制开始时间,Unix 时间戳,单位秒
RecordStopTime
Integer
录制停止时间,Unix 时间戳,单位秒
TotalTime
Integer
回放视频总时长(单位:毫秒)
ReplayUrl
String
视频回放地址,仅适用于视频生成模式,需要配合信令播放器进行回放。可以参考 视频回放 中的 视频生成模式 了解更多的细节
VideoInfos
Array of VideoInfo
录制视频列表
以下为一个录制结果 JSON 串示例:
{
"RoomId":1234,
"GroupId":"1234",
"RecordStartTime":1558613140,
"RecordStopTime":1558614640,
"TotalTime": 1440000,
"VideoInfos":[
{
"VideoPlayTime":0,
"VideoSize":13151,
"VideoFormat":"mp4",
"VideoDuration":900000,
"VideoUrl":"http://1253488539.vod2.myqcloud.com/oM86K7X3Ig8b.mp4",
"VideoId":"5285890781570653827",
"VideoType":0,
"UserId":"ios_test1"
},
{
"VideoPlayTime":300000,
"VideoSize":3756,
"VideoFormat":"mp4",
"VideoDuration":600000,
"VideoUrl":"http://1253488539.vod2.myqcloud.com/oM86K7X3IsdfA.mp4",
"VideoId":"5285890781570653828",
"VideoType":0,
"UserId":"pc_test1"
},
{
"VideoPlayTime":120000,
"VideoSize":1241,
"VideoFormat":"mp4",
"VideoDuration":780000,
"VideoUrl":"http://1253488539.vod2.myqcloud.com/52lk3KA0A562.mp4",
"VideoId":"5285890781570653830",
"VideoType":2,
"UserId":""
},
{
"VideoPlayTime":900000,
"VideoSize":13151,
"VideoFormat":"mp4",
"VideoDuration":300000,
"VideoUrl":"http://1253488539.vod2.myqcloud.com/oM86K7X3Ig63.mp4",
"VideoId":"5285890781570653841",
"VideoType":0,
"UserId":"ios_test1"
},
{
"VideoPlayTime":900000,
"VideoSize":3756,
"VideoFormat":"mp4",
"VideoDuration":210000,
"VideoUrl":"http://1253488539.vod2.myqcloud.com/oM86K7X3Isd15.mp4",
"VideoId":"5285890781570653842",
"VideoType":0,
"UserId":"pc_test1"
},
{
"VideoPlayTime":900000,
"VideoSize":1241,
"VideoFormat":"mp4",
"VideoDuration":540000,
"VideoUrl":"http://1253488539.vod2.myqcloud.com/52lk3KA0A512.mp4",
"VideoId":"5285890781570653843",
"VideoType":2,
"UserId":""
}
]
}
此 JSON 对象表示课堂录制产生了6个视频文件,其中,在过程中暂停录制了1分钟,之后恢复录制,因此最后产生了6段视频,这6个视频文件在时间轴上的排列如下图所示:




视频回放

实时录制模式
实时录制模式的录制结果是标准的mp4视频文件,直接使用标准播放器进行播放即可。
视频生成模式
视频生成模式进行视频回放的时候,有两种方式:
1. 重新生成视频后,使用标准播放器进行播放。
2. 使用特殊播放器对录制结果里的回放链接进行播放(推荐)。
下边详细说明第2种方式的使用方法。
在停止录制并拿到回放链接后,您需要使用特殊的播放器才能对回放链接进行回看,我们提供了基于 Web 页面的播放器供您使用,您只需按如下所示拼接 URL,即可在浏览器内观看回放。
https://sdk.qcloudtiw.com/web/replay/index.html?url=回放链接&showChatMessages=1
其中,url 参数指向回放链接,showChatMessages 参数为1表示回放时需要展示 IM 聊天消息。
目前,我们的播放器对各平台浏览器的适配情况如下:
平台
支持的浏览器及其最低版本
已知问题
Windows
Chrome、Microsoft Edge
macOS
Chrome、Safari
Android
Chrome、系统浏览器、QQ、微信、企业微信
iOS
Safari、QQ、微信、企业微信
信令播放器回放工作原理如下所示:



重新生成视频(视频生成模式)

注意
此小节仅在使用视频生成模式时需要关注,仅使用实时录制模式可忽略此内容。
由于视频生成模式在录制的过程中不会自动生成视频文件,如果需要视频文件,可以选择在录制结束后,通过视频生成相关接口来通知录制服务生成相应视频。

创建视频生成任务

注意
创建成功的视频生成任务会在视频房间内所有人都退出后才会开始进行视频生成。
您可以使用 创建视频生成任务 接口来通知录制服务进行生成视频,在请求的时候可以选择使用不一样的混流布局来生成不一样的混流视频。
说明
由于网络延迟等因素,发送请求后,实际录制操作将在2s左右后进行。 目前服务端 API 接口只支持区域广州,在调用 API 时,Region 参数请填写ap-guangzhou

获取视频生成结果

在视频生成任务完成后,您如果设置了回调地址,录制服务会把视频生成结果回调到指定的地址。另外,您也可以使用 查询视频生成任务 接口来主动查询视频生成结果。
两种方式获取到的视频生成结果数据格式与字段含义与实时录制模式的结果相同,具体解析可参考 解析录制任务结果
说明
由于网络延迟等因素,发送请求后,实际录制操作将在2s左右后进行。 目前服务端 API 接口只支持区域广州,在调用 API 时,Region参数请填写ap-guangzhou