使用场景
快速生成回放文件
直播回放可以将优质资源的价值进行放大,降低优质资源的成本,从而提升收益,通过全景录制功能可以在用户的视角将上课的内容实时录制下来,课程结束之后可以根据 Serverless 庞大的算力池快速转码,形成录制文件,实时生成回放。
精彩瞬间
家长很少有时间全程观看孩子的上课视频,通过精彩瞬间可以将孩子上课过程精彩表现呈现给家长,提升家长对与课程的认知度和认可感,针对上课过程中录制的文件,可以使用 H5 平台将上课的精彩内容截取下来,然后采取全景录制生成 mp4 文件,通过 CDN 快速分发,形成孩子上课过程的精彩集锦。
文件合成
常规的文件合成需要转码,对于算力的消耗较大,将视频、声音、图片等,在一个前端页面进行合成,进行布局调整,采取全景录制进行录制,多路解码,一路编码,快速生成视频文件,最大程度使用算力资源。
架构原理
腾讯云自研的全景录制,主打所见即所得的录制理念,只需要用户提供一个可供访问的公网链接,采取 Chrome 进行页面渲染录制,ffmepg 转码,同时直接上传到 COS,实时生成录制文件。结合直播、点播、 TRTC 等腾讯云产品,提供教育,游戏,互娱等一站式数据解决方案。
应用优势
- 更低成本
通过 Chrome 完成多路解码,一路解码,算力消耗降低,与传统录制方案相比,成本可以降低60%以上。
- 高度还原
客户端上课过程中所有的特效等外部信息都可以捕捉到,达到100%实现课堂实际效果。
- 自由切换
录制过程中可以灵活调整浏览器布局,灵活操作和切换老师,学生等视角。
- 超高并发
云函数计算实例支持快速启动,高并发承载能力稳定,轻松面对突发的业务峰值。
- 即刻出片
用户直播结束之后可以直接拿到回放,不需要进行复杂的合成工作,省时高效。
应用资源
全景录制应用部署后,将为您创建以下资源:
- 云函数 : 获取外部链接数据,通过全景录制实时进行录制。
- CLS 日志 :处理过程的日志会存储在日志服务 CLS 中,可能会产生一定计费,详情可参见 CLS 计费规则。
- API 网关 :通过 API 网关触发器进行事件触发。
前提条件
- 配置部署账号权限。参考 账号和权限配置。
- 配置 运行角色 权限。
- 全景录制需要和其他服务关联使用,需要添加以下策略:QcloudRedisFullAccess、QcloudVPCFullAccess、QcloudCFSFullAcces、QcloudSCFFullAccess、QcloudCOSFullAccess、QcloudAccessForScfRole 权限。详情请参见 策略绑定。
操作步骤
创建依赖资源
函数创建的过程中,需要依赖以下相关组件,请提前创建。具体创建流程可参考 VPC 创建、CFS 创建、COS 创建、Redis 创建。
创建全景录制应用
- 登录 Serverless 控制台,选择左侧导航栏中的 Serverless 应用。
- 在 “Serverless 应用” 页面,单击新建应用。
- 在新建应用页面,根据页面相关信息提示进行配置。
- 创建方式:选择应用模板。
- 模糊搜索:输入“全景”进行搜索,选择全景录制。
单击模板中的查看详情,即可在弹出的“模板详情”窗口中查看相关信息,支持下载操作。
- 单击下一步,根据页面相关信息提示进行配置。
- 应用名:例如,“record-app”。
- 地域:例如,“上海”。
- 中间结果存储:录制过程临时文件存放位置,可以根据自己需求选择 COS 或者 CFS。
- 目标存储:录制结果的最终存放位置,可以根据需要选择 VOD 或者 COS。
- 文件系统:按需选择即可。
- redis:按需选择即可。
- 单击完成即可完成应用创建、函数创建以及 API 网关触发器创建。
如需根据业务场景修改函数配置,可通过 Serverless 应用 > 资源列表 > 函数详情 进行修改。如下图所示:
说明
- 录制应用如需要依赖云函数长时运行能力,可参见 异步执行。
- 为避免请求超时,API 网关触发器的后端超时建议设置较大数值。或采取预置,具体请参考 预置说明。
接口使用说明
使用前提
- 准备一个可以通过 URL 访问的 WEB 页面作为录制内容来源,此页面需兼容 Chrome。
- 用于录制的页面需要自行处理可能存在的登录态或者鉴权。
- 用于录制的页面如果需要播放多媒体,需要自行处理多媒体的播放、跳转、停止等操作。
- 用于录制的页面需要在指定的宽高内完整的显示所有内容,不能有滚动条,因为 WEB 全景录制只能录制浏览器窗口的可见区域,超出可见区的内容不会被录制下来。
接口请求路径
- 登录 Serverless 控制台,选择左侧导航栏中的 Serverless 应用。
- 在 Serverless 应用列表页,单击应用名称。
- 在应用详情页,获取触发器访问入口。如下图所示:
POST
Content-Type: application/json
全景录制服务接口由云函数实现,采用了 API 网关触发器方式对外提供服务,鉴权采用应用认证方式(ApiAppKey 和 ApiAppSecret),详情可参见 应用鉴权。
开始录制接口
通过此接口可以发起全景录制,在接口参数中指定录制 URL,录制分辨率,录制结果回调地址等参数。
参数 | 类型 | 必填 | 说明 |
---|
Action | string | 是 | 请求操作类型,开始录制为 Start |
Data | object | 是 | 请求协议参数 |
RecordURL | string | 是 | 需要录制的 WEB 页面访问 URL,需要 Chrome 浏览器能够访问。 |
ManualStart | bool | 是 | 创建的录制任务是否需要等待页面主动调用 window.startRecord 方法触发开始录制,默认为 false,录制任务会自动开始录制,当值被设置为 true 时,录制函数加载页面后,不会自动开始录制,而是等待页面主动调用 window.startRecord 方法才会触发开始录制 |
Width | number | 否 | 录制画面宽度,默认为1280,合法取值范围 [0, 2560] |
Height | number | 否 | 录制画面高度,默认为720,合法取值范围 [0, 2560] |
CallbackURL | string | 否 | 录制结果通知回调地址 |
MaxDurationLimit | int | 否 | 录制最大时长限制, 单位s,合法取值范围 [0, 36000],默认21600s(6小时),超过6小时需要配置永久密钥 |
StorageType | string | 否 | 录制过程中中间态 webm 文件的存储位置,可选参数为cos ,不填写默认为cfs 。(如果环境变量配置了COS_BUCKET_RAW这个参数,会写在这个桶里面,不配置会写在目标存储桶的 raw 路径下) |
Output | object | 否 | 请求协议参数 |
Cos | object | 否 | 请求协议参数 |
Domain | string | 否 | 录制文件回放域名,不设置为默认源站域名 |
Bucket | string | 否 | 录制文件存放空间,不设置默认为创建函数时设置的存储空间 |
Region | string | 否 | 录制文件存放区域,默认为存储空间所在区域 |
TargetDir | string | 否 | 录制文件存放路径,不设置默认为 Taskid |
TargetName | string | 否 | 录制文件名称,不设置为结束时间戳 |
Vod | object | 否 | VOD配置参数 |
MediaInfo | object | 否 | VOD配置媒体信息 |
MediaName | string | 否 | 媒体名称 |
ExpireTime | Timestamp ISO8601 | 否 | 媒体文件过期时间,格式按照 ISO 8601 标准表示,详见 ISO 日期格式 |
StorageRegion | string | 否 | 指定上传园区,仅适用于对上传地域有特殊需求的用户 |
ClassId | Integer | 否 | 分类 ID,用于对媒体进行分类管理,可通过 创建分类 接口,创建分类,获得分类 ID |
SourceContext | string | 否 | 来源上下文,用于透传用户请求信息,VOD的上传完成回调 将返回该字段值,最长 250 个字符 |
ProcedureInfo | object | 否 | 任务流信息 |
Procedure | string | 否 | 媒体后续任务处理操作,即完成媒体上传后,可自动发起任务流操作。参数值为任务流模板名,云点播支持 创建模版 并为模板命名。 |
SessionContext | string | 否 | 会话上下文,用于透传用户请求信息,当指定 Procedure 参数后,任务流状态变更回调 将返回该字段值,最长 1000 个字符。 |
SubAppId | string | 否 | 点播 子应用 ID。如果要访问子应用中的资源,则将该字段填写为子应用 ID;否则无需填写该字段 |
Video | object | 否 | 请求协议参数 |
Muxer | string | 否 | 录制文件格式,可选 hls、mp4,不写默认为 mp4 |
EncryptKey | string | 否 | hls加密公钥,不设置默认不加密 |
AuthUrl | string | 否 | 解密私钥地址,设置公钥的情况下必填参数 |
{
"Action": "Start",
"Data": {
"RecordURL": "https://web-record-12596******.cos.ap-chengdu.myqcloud.com/test/ponyo.mp4",
"Width": 1280,
"Height": 720,
"CallbackURL": "http://xxx/webrecord/callback",
"MaxDurationLimit": 21600,
"Output":{
"Cos":{
"Domain":"abc.xxx.com",
"Bucket":"webrecord-xxx",
"Region":"ap-shanghai",
"TargetDir":"11234/",
"TargetName":"record-file-name.mp4"
},
"Vod": {
"MediaInfo": {
"MediaName": "test",
"ExpireTime": "2023-10-01T10:00:00Z",
"StorageRegion": "ap-shanghai",
"ClassId": 1
},
"ProcedureInfo": {
"Procedure": "",
"SessionContext": ""
},
"SubAppId": 1500007120
},
"Video": {
"Muxer": "hls",
"EncryptKey": "21834cca41778803e1afba3f41e70c90",
"AuthUrl": "https://hls-web-record-1253970226.cos.ap-shanghai.myqcloud.com/m3u8-encrypt/enc.key"
}
}
}
}
参数 | 类型 | 必填 | 说明 |
---|
ErrorCode | string | 否 | 错误类型,只有请求出错的时候才会返回此字段 |
ErrorMessage | string | 否 | 错误说明,只有请求出错的时候才会返回此字段 |
TaskID | string | 否 | 录制任务 ID,只有开始录制成功的时候才会返回此字段 |
RequestID | string | 否 | 请求 ID |
// 成功返回
{
"TaskID": "d1806f20-25b8-4c30-8176-c0832b**",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
// 失败返回
{
"ErrorCode": "InvalidParam",
"ErrorMessage": "RecordURL missing",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
暂停录制接口
使用暂停录制接口可以将已经开始录制的任务暂时停止录制。
参数 | 类型 | 必填 | 说明 |
---|
Action | string | 是 | 请求操作类型,暂停录制为 Pause |
Data | object | 是 | 请求协议参数 |
Data.TaskID | string | 是 | 需要暂停录制的录制任务 ID,录制任务 ID 可以在开始录制的接口返回参数中获取到 |
{
"Action": "Pause",
"Data": {
"TaskID": "0f7d9522-a1a3-4517-b5ad-7a6eca**"
}
}
参数 | 类型 | 必填 | 说明 |
---|
ErrorCode | string | 否 | 错误类型,只有请求出错的时候才会返回此字段 |
ErrorMessage | string | 否 | 错误说明,只有请求出错的时候才会返回此字段 |
TaskID | string | 否 | 录制任务 ID,只有开始录制成功的时候才会返回此字段 |
RequestID | string | 否 | 请求 ID |
// 成功返回
{
"TaskID": "d1806f20-25b8-4c30-8176-c0832b**",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
// 失败返回
{
"ErrorCode": "InvalidParam",
"ErrorMessage": "TaskID missing",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
恢复录制接口
使用恢复录制接口可以将已暂停的录制任务重新开始录制。重新开始录制的视频内容将直接追加在暂停之前的内容后面,不会产生视频分段。
参数 | 类型 | 必填 | 说明 |
---|
Action | string | 是 | 请求操作类型,恢复暂停录制为 Resume |
Data | object | 是 | 请求协议参数 |
Data.TaskID | string | 是 | 需要恢复录制的录制任务 ID,录制任务 ID 可以在开始录制的接口返回参数中获取到 |
{
"Action": "Resume",
"Data": {
"TaskID": "0f7d9522-a1a3-4517-b5ad-7a6eca**"
}
}
参数 | 类型 | 必填 | 说明 |
---|
ErrorCode | string | 否 | 错误类型,只有请求出错的时候才会返回此字段 |
ErrorMessage | string | 否 | 错误说明,只有请求出错的时候才会返回此字段 |
TaskID | string | 否 | 录制任务 ID,只有开始录制成功的时候才会返回此字段 |
RequestID | string | 否 | 请求 ID |
// 成功返回
{
"TaskID": "d1806f20-25b8-4c30-8176-c0832b**",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
// 失败返回
{
"ErrorCode": "InvalidParam",
"ErrorMessage": "TaskID missing",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
刷新录制页面
使用刷新录制接口发起刷新录制页面请求。
参数 | 类型 | 必填 | 说明 |
---|
Action | string | 是 | 请求操作类型,刷新录制为 Refresh |
Data | object | 是 | 请求协议参数 |
Data.TaskID | string | 是 | 需要刷新的录制任务 ID,录制任务 ID 可以在开始录制的接口返回参数中获取到 |
{
"Action": "Refresh",
"Data": {
"TaskID": "0f7d9522-a1a3-4517-b5ad-7a6eca**"
}
}
参数 | 类型 | 必填 | 说明 |
---|
ErrorCode | string | 否 | 错误类型,只有请求出错的时候才会返回此字段 |
ErrorMessage | string | 否 | 错误说明,只有请求出错的时候才会返回此字段 |
TaskID | string | 否 | 录制任务 ID,只有开始录制成功的时候才会返回此字段 |
RequestID | string | 否 | 请求 ID |
// 成功返回
{
"TaskID": "d1806f20-25b8-4c30-8176-c0832b**",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
// 失败返回
{
"ErrorCode": "InvalidParam",
"ErrorMessage": "TaskID missing",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
停止录制接口
使用停止录制接口发起结束录制请求。
参数 | 类型 | 必填 | 说明 |
---|
Action | string | 是 | 请求操作类型,结束录制为 Stop |
Data | object | 是 | 请求协议参数 |
Data.TaskID | string | 是 | 需要取消的录制任务 ID,录制任务 ID 可以在开始录制的接口返回参数中获取到 |
{
"Action": "Stop",
"Data": {
"TaskID": "0f7d9522-a1a3-4517-b5ad-7a6eca**"
}
}
参数 | 类型 | 必填 | 说明 |
---|
ErrorCode | string | 否 | 错误类型,只有请求出错的时候才会返回此字段 |
ErrorMessage | string | 否 | 错误说明,只有请求出错的时候才会返回此字段 |
TaskID | string | 否 | 录制任务 ID,只有开始录制成功的时候才会返回此字段 |
RequestID | string | 否 | 请求 ID |
// 成功返回
{
"TaskID": "d1806f20-25b8-4c30-8176-c0832b**",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
// 失败返回
{
"ErrorCode": "InvalidParam",
"ErrorMessage": "TaskID missing",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
查询录制任务信息接口
使用查询任务信息接口发起查询录制任务信息请求。
参数 | 类型 | 必填 | 说明 |
---|
Action | string | 是 | 请求操作类型,查询录制任务信息为 Describe |
Data | object | 是 | 请求协议参数 |
Data.TaskID | string | 是 | 需要查询的录制任务 ID,录制任务 ID 可以在开始录制的接口返回参数中获取到 |
{
"Action": "Describe",
"Data": {
"TaskID": "0f7d9522-a1a3-4517-b5ad-7a6ec**"
}
}
参数 | 类型 | 必填 | 说明 |
---|
ErrorCode | string | 否 | 错误类型,只有请求出错的时候才会返回 |
ErrorMessage | string | 否 | 错误说明,只有请求出错的时候才会返回 |
TaskID | string | 否 | 录制任务 ID,只有开始录制成功的时候才会返回 |
RequestID | string | 否 | 请求 ID |
Status | string | 否 | 录制任务当前状态,可能的取值及其含义如下: normal -- 录制任务创建成功,但录制任务还没有开始录制 recording -- 录制任务正在录制中 paused -- 录制任务被暂停 canceled -- 录制任务已经被取消 transcode -- 录制任务正在对录制视频进行拼接、转码等操作 upload -- 录制任务正在上传录制视频到云存储 callback -- 录制任务正在把录制结果通过发起录制时配置的回调地址进行通知 finished -- 录制任务的所有操作已经完成 |
CreateTime | int | 否 | 录制任务创建时间戳,单位s |
StartTime | int | 否 | 录制任务开始录制时间戳,单位s,只有开始录制后才会返回此字段 |
CancelTime | int | 否 | 录制任务被取消的时间戳,单位s,只有发起过取消录制请求才会返回此字段 |
StopTime | int | 否 | 录制任务结束录制时间戳,单位s,只有录制任务停止后才会返回此字段 |
FinishTime | int | 否 | 录制任务完成录制时间戳,单位s,只有录制任务完成所有录制处理后才会返回此字段 |
Result | object | 否 | 录制任务结果 |
Result.ErrorCode | string | 否 | 录制任务出错类型,只有录制任务执行过程中出现错误时才会返回此字段 |
Result.ErrorMessage | string | 否 | 录制任务出错信息,只有录制任务执行过程中出现错误时才会返回此字段 |
Result.Videos | []object | 否 | 录制视频文件列表 |
Result.Videos.Filename | string | 否 | 视频文件名称 |
Result.Videos.FileSize | int | 否 | 视频文件大小 |
Result.Videos.FileDuration | string | 否 | 视频文件长度 |
Result.Videos.FileId | string | 否 | 如果目标为 VOD,该参数为 VOD 中媒体文件的唯一标识 |
Result.Videos.FileURL | string | 否 | 视频文件链接 |
// 成功返回
{
"TaskID": "7a035551-d9d6-494e-b604-fa787b**",
"RequestID": "95941e2c85898384a95b81c2a5**",
"CreateTime": 1620982173,
"Status": "finished",
"StartTime": 1620982177,
"CancelTime": 1620982203,
"StopTime": 1620982203,
"FinishTime": 1620982210,
"Result": {
"Videos": [
{
"Filename": "1621406865789.mp4",
"FileSize": 169780,
"FileDuration": 9,
"FileId": 31235664578998,
"FileURL": "http://web-record-125******.cos.ap-chengdu.myqcloud.com/4d0f336d-4de4-4fc8-b505-d1f790974909/162140******.mp4"
}
]
}
}
// 请求出错返回
{
"ErrorCode": "InvalidParam",
"ErrorMessage": "TaskID missing",
"RequestID": "95941e2c85898384a95b81c2a5**"
}
// 录制任务出错返回
{
"TaskID": "7a035551-d9d6-494e-b604-fa787b**",
"RequestID": "95941e2c85898384a95b81c2a5**",
"CreateTime": 1620982173,
"Status": "finished",
"StartTime": 1620982177,
"CancelTime": 1620982203,
"StopTime": 1620982203,
"FinishTime": 1620982210,
"Result": {
"ErrorCode": "CallbackFailed",
"ErrorMessage": "Callback failed even all tries. last error message:ECONNABORTED:timeout of 2000ms exceeded"
}
}
本页内容是否解决了您的问题?