本文主要介绍腾讯云短视频小程序解决方案 Demo 的整体设计,方便开发者理解和参考。该方案涉及到以下的 VOD 特性,了解这些特性可以帮助开发者更好地阅读本文。
媒资管理:删除视频。
系统框架
系统主要涉及三个组成部分:客户端、业务后台和 VOD,如下图所示:
Demo 所提供的是客户端和业务后台两部分的源码。
业务逻辑
小程序用户登录
登录是客户端和业务后台之间的逻辑,交互流程不涉及 VOD,如下图所示:
用户登录时,微信小程序前端调用
wx.login
接口获取登录凭证 code。向业务后台发起登录请求。业务后台会根据登录凭证
code
,调用微信接口auth.code2Session
换取用户登录态信息,包括用户的唯一标识 openid
及本次登录的会话密钥 session_key
等,后台将会把 openid
作为小程序用户的授权信息。如果获取失败则会返回错误。如果业务后台在数据库授权信息( UserAuth 表)中没有找到对应授权信息(即 openid ),则自行创建一个全局唯一的用户,昵称和密码通过随机生成,将该用户 ID 与授权信息保存在数据库中;如果找到对应授权信息(即 openid),则会获得对应的用户 ID。
业务后台为用户生成一个 Token 并返回。
用户管理
用户是客户端和业务后台之间的逻辑,交互流程不涉及 VOD,如下图所示:
修改用户资料流程
1. 用户在 App 的修改资料界面上填写需要修改的资料字段,然后向业务后台发起请求。
2. 业务后台校验请求中 Token 的合法性,如果不合法,返回错误码;如果合法则修改数据库中的对应数据。
3. 业务后台返回成功。
拉取用户资料流程
1. 用户在 App 上访问用户信息界面,客户端将向业务后台发起请求。
2. 业务后台校验请求中 Token 的合法性,如果不合法,返回错误码;如果合法则读取数据库中的对应数据。
3. 业务后台将用户资料返回给客户端。
上传视频
上传视频流程同时涉及到客户端、业务后台和 VOD,如下图所示:
1. 用户在 App 上录制、编辑视频,单击 发布,客户端将向业务后台请求客户端上传签名。
2. 业务后台校验请求中 Token 的合法性,在校验通过后生成一个上传签名并返回给客户端。
3. 客户端将视频上传到 VOD 的存储中。
4. VOD 向业务后台发起一个视频上传完成回调。
5. 业务后台根据回调中的信息(视频 ID、URL、上传者等),在数据库的媒资中生成一条视频记录,并标记为未审核。
6. VOD 后台自动对视频发起一个视频处理任务流,其中包含有内容审核任务,在审核完成后向业务后台发起一个任务流状态变更回调。
7. 业务后台根据回调中的信息(视频 ID、审核结果等),修改数据库中对应的视频状态信息(审核通过或不通过)。
8. 业务后台在上传视频审核回调状态变为通过时,会调用 VOD 微信小程序视频发布接口
9. VOD 后台会将点播视频发布到微信小程序,供微信小程序播放器播放。
10. 业务后台根据发布任务回调中的信息(视频 ID、审核结果等),修改数据库中对应的微信小程序视频发布状态(发布通过或不通过)。
媒资管理
媒资管理主要指对视频信息的增加、删除、修改和搜索。Demo 中主要涉及的有两个操作:拉取视频列表(分为拉取全局视频、拉取自己上传的视频两种形式)、删除自己上传的视频。如下图所示:
拉取全局视频列表
1. 用户进入小程序首页或者在首页下拉刷新时,微信小程序客户端会向业务后台请求全局视频列表。
2. 拉取全局视频列表不需要 Token(即非注册用户也可以访问),业务后台在数据库中查找最近上传的若干视频,并获取视频的信息(URL、封面、上传者等)。
3. 业务后台将视频列表返回给客户端。
拉取自己上传的视频列表
1. 用户进入 我 界面后,客户端会向业务后台请求自己上传的视频列表。
2. 业务后台校验 Token 的合法性,如果不合法,返回错误码。如果合法则在数据库中查找该用户最近上传的若干视频,并获取视频的信息(URL、封面、上传者等)。
3. 业务后台将视频列表返回给客户端。
删除视频
1. 用户在 我 界面单击自己上传过的视频,然后单击 删除,客户端会向业务后台发出删除请求。
2. 业务后台校验 Token 的合法性,如果不合法,返回错误码;如果合法则删除数据库中的对应记录。
3. 业务后台向 VOD 发起删除请求,清理 VOD 上存储的视频数据。
4. 业务后台返回处理结果给客户端。
播放视频
客户端在拉取视频列表时,已经获取到了视频的 URL 并缓存,如果 VOD 已经开启了 Key 防盗链,那么业务后台返回的视频 URL 会带有防盗链签名。当用户单击视频时,若 VOD 并未开启 Key 防盗链,或者防盗链签名尚未过期,则客户端可以直接使用缓存的 URL 进行播放(下图蓝色虚线)。如果开启了 Key 防盗链并且缓存 URL 的防盗链签名已经过期,那么就需要重新获取(下图黑色实线)。
其它
Token
注册和登录后,客户端会收到业务后台派发的 Token。在后续的请求中,客户端需要带上这个 Token 来表明自己的身份(除了不需要验证身份的协议)。
Header 的格式如下,为典型的 JWT 头部。
{"alg": "HS256","typ": "JWT"}
Payload 的格式如下,其中 UserId 为用户 ID;exp 为该 Token 过期时间; iat 为该 Token 创建时间。
{"UserId": "3a982a4d-3d31-48d8-857d-72a432aec1f8","exp": 1585821621,"iat": 1585814421}
Signature 使用 HMAC SHA256(如 Header 中的声明)对 Header 和 Payload 进行签名,使用的密钥在业务后台源码
src/service/token.ts
中。上传签名
任务流参数:
procedure=short-video-demo
该参数是视频上传完成后,VOD 后台自动对视频发起指定的任务流。该任务流是在部署脚本中自动创建的,其中的任务包括内容审核、截取视频首帧做封面。
来源上下文参数:
sourceContext={"UserId":"be7bdf8c-ba5f-477c-8802-7a1c6ddc0f58"}
业务后台将上传者的用户 ID 填入
sourceContext
参数,其内容会在上传完成回调中透传给业务后台,因此业务后台可以据此得知视频的上传者并写入媒资。接口协议
请求形式
HTTP 请求,Method 为 POST,业务参数以 JSON 格式填入 HTTP Body 中,需要指定以下 Header:
Content-Type: application/json
回包形式
{"RequestId": "0ab970c8-5453-4c76-972d-0e75bd330804","Code": 50011,"Message": "NickName is not unique","Data": {}}
协议内容
微信小程序用户登录 WXAMPLogin
请求:
参数名称 | 数据类型 | 是否必填 | 说明 |
Code | String | 是 | 小程序前端通过 wx.login 获取登录凭证 code,传递到后端,由后端换取 openid,并作为授权信息保存。 |
回包:
参数名称 | 数据类型 | 说明 |
UserId | String | 用户 ID,由业务后台生成,全局唯一。 |
Token | String | 用户身份凭证,即登录态。 |
TokenExpireTime | String | Token 过期时间,ISO 8601 日期格式。 |
NickName | String | 用户昵称,全局唯一,微信小程序用户由系统自动生成。 |
Avatar | String | 用户头像 ID。 |
Description | String | 用户简介,不多于80个字符。 |
修改用户资料 ModifyUserInfo
请求:
参数名称 | 数据类型 | 是否必填 | 说明 |
Token | String | 是 | 用户身份凭证,注册/登录后获取。 |
NickName | String | 否 | 用户昵称,修改昵称时需填写,全局唯一,由英文字母、数字和下划线组成,4~24个字符。 |
Avatar | String | 否 | 用户头像 ID,修改头像时需填写,不多于32个字节。 |
Description | String | 否 | 用户简介,修改简介时需填写,不多于80个字符。 |
获取上传签名 GetUploadSign
请求:
参数名称 | 数据类型 | 是否必填 | 说明 |
Token | String | 是 | 用户身份凭证,注册/登录后获取。 |
回包:
参数名称 | 数据类型 | 说明 |
UploadSign | String | 上传签名。 |
ExpireTime | String | 上传签名过期时间,ISO 8601 日期格式。 |
拉取微信小程序发布的视频列表 WXAMPGetVideoList
请求:
参数名称 | 数据类型 | 是否必填 | 说明 |
Offset | Integer | 否 | 分页拉取的偏移量,默认0。 |
Limit | Integer | 否 | 分页拉取的条数,默认10,最大100。 |
回包:
参数名称 | 数据类型 | 说明 |
VideoList | Array | 视频列表。 |
VideoList.Id | String | 视频 ID,在上传时由 VOD 后台生成,全局唯一。 |
VideoList.Title | String | 视频名称,不多于64个字符。 |
VideoList.Url | String | 视频播放地址,可带防盗链签名。 |
VideoList.UrlExpireTime | String | URL 中防盗链签名(如果有)的过期时间,ISO 8601日期格式。 空字符串表示签名永久有效或未开启防盗链。 |
VideoList.Cover | String | 封面地址。 |
VideoList.AnimatedCover | String | 动图封面地址。 |
VideoList.CreateTime | String | 创建时间,ISO 8601 日期格式。 |
VideoList.AuthorId | String | 上传者的用户 ID。 |
VideoList.AuthorNickname | String | 上传者昵称。 |
VideoList.AuthorAvatar | String | 上传者头像 ID。 |
VideoList.Width | Number | 视频显示长度,单位:px。 |
VideoList.Height | Number | 视频显示宽度,单位:px。 |
VideoList.Status | String | 视频上传状态。 |
VideoList.WechatMiniProgramStatus | String | 视频微信小程序发布状态。 |
拉取指定用户上传的视频列表 GetVideoListByUser
请求:
参数名称 | 数据类型 | 是否必填 | 说明 |
Token | String | 是 | 身份凭证,注册/登录后获取。 |
UserId | String | 是 | 用户 ID,用于指定要拉取哪一个用户上传的视频。 |
Offset | Integer | 否 | 分页拉取的偏移量,默认0。 |
Limit | Integer | 否 | 分页拉取的条数,默认10,最大100。 |
回包:
参数名称 | 数据类型 | 说明 |
VideoList | Array | 视频列表。 |
VideoList.Id | String | 视频 ID,在上传时由 VOD 后台生成,全局唯一。 |
VideoList.Title | String | 视频名称,不大于64个字符。 |
VideoList.Url | String | 视频播放地址,可带防盗链签名。 |
VideoList.UrlExpireTime | String | URL 中防盗链签名(如果有)的过期时间,ISO 8601 格式。 空字符串表示签名永久有效或未开启防盗链。 |
VideoList.Cover | String | 封面地址。 |
VideoList.AnimatedCover | String | 动图封面地址。 |
VideoList.CreateTime | String | 创建时间,ISO 8601 日期格式。 |
VideoList.AuthorId | String | 上传者的用户 ID。 |
VideoList.AuthorNickname | String | 上传者昵称。 |
VideoList.AuthorAvatar | String | 上传者头像 ID。 |
VideoList.Width | Number | 视频显示长度,单位:px。 |
VideoList.Height | Number | 视频显示宽度,单位:px。 |
VideoList.Status | String | 视频上传状态: PASS:审核通过 NOT_PASS:审核不通过 FAIL:审核失败 PROCESSING:审核中 |
VideoList.WechatMiniProgramStatus | String | 视频微信小程序发布状态: PASS:审核通过 NOT_PASS:审核不通过 FAIL:审核失败 |
删除视频 DeleteVideo
请求:
参数名称 | 数据类型 | 是否必填 | 说明 |
Token | String | 是 | 用户身份凭证,注册/登录后获取。 |
VideoList | Array | 是 | 待删除的视频列表。 |
VideoList.Id | String | 是 | 待删除的视频 ID。 |
获取视频播放地址 PlayVideo
请求:
参数名称 | 数据类型 | 是否必填 | 说明 |
VideoId | String | 是 | 要播放的视频 ID。 |
回包:
参数名称 | 数据类型 | 说明 |
VideoId | String | 视频 ID。 |
VideoList.Url | String | 视频播放地址,可带防盗链签名。 |
VideoList.UrlExpireTime | String | URL 中防盗链签名(如果有)的过期时间,ISO 8601 日期格式。 空字符串表示签名永久有效或未开启防盗链。 |
错误码
错误码 | 含义 |
10001 | 参数长度不合法。 |
10002 | 参数内容不合法。 |
40301 | Token 不合法。 |
50000 | 服务端内部错误:未分类错误。 |
50001 | 服务端内部错误:新增用户失败。 |
50002 | 密码不正确。 |
50003 | 服务端内部错误:更新密码失败。 |
50004 | 服务端内部错误:更新用户信息失败。 |
50005 | 服务端内部错误:查找用户失败。 |
50006 | 找不到用户。 |
50007 | 服务端内部错误:查找视频列表失败。 |
50008 | 查找视频失败。 |
50009 | 服务端内部错误:保存视频失败。 |
50016 | 服务端内部错误:更新视频失败。 |
50010 | 服务端内部错误:删除视频失败。 |
50011 | 用户名重复。 |
50012 | 用户第三方授权重复。 |
50013 | 服务端内部错误:查询用户第三方授权信息失败。 |
50014 | 服务端内部错误:保存用户第三方授权失败。 |
50015 | 授权信息校验失败。 |
数据库设计
User 表
字段名 | 字段类型 | 字段属性 | 含义 |
id | varchar(36) | PRI | 用户 ID。 |
password | varchar(32) | - | 用户密码。 |
create_time | timestamp | - | 用户创建时间。 |
update_time | timestamp | - | 用户资料更新时间。 |
nickname | varchar(128) | UNI | 用户昵称。 |
sys_avatar_id | varchar(32) | - | 用户系统头像 ID。 |
custom_avatar_url | varchar(256) | - | 用户自定义头像 URL。 |
description | varchar(256) | - | 用户介绍。 |
UserAuth 表
字段名 | 字段类型 | 字段属性 | 含义 |
id | varchar(36) | PRI | 授权信息 ID。 |
user_id | varchar(36) | - | 用户 ID。 |
type | varchar(128) | - | 授权类型。 |
auth_info | varchar(256) | - | 授权信息。 |
Video 表
字段名 | 字段类型 | 字段属性 | 含义 |
id | varchar(32) | PRI | 视频 ID。 |
title | varchar(128) | - | 视频名称。 |
create_time | timestamp | - | 视频创建时间。 |
author | varchar(36) | - | 上传者用户 ID。 |
cover | varchar(256) | UNI | 视频图片封面 URL。 |
animated_cover | varchar(256) | - | 视频动图封面 URL。 |
status | varchar(32) | - | 视频审核状态。 |
wechat_mini_program_status | varchar(32) | - | 微信小程序视频发布状态。 |
url | varchar(256) | - | 视频 URL。 |
业务安全注意事项
短视频 Demo 主要是为开发者展示短视频解决方案的能力及易用性。为了方便部署以及降低理解成本,Demo 在安全性设计上尽量简化,未达到生产环境的要求,请开发者留意。
通信方式:客户端和业务后台使用 HTTP 进行通信,通信内容容易被监听。如果开发者想替换为 HTTPS,涉及到的主要工作有 注册域名和实名认证、网站备案、域名解析、在 CVM 上使用 Nginx/Apache 部署 HTTPS 证书(请搜索网上教程)等。
用户密码传输和存储:注册协议和登录协议中传输的是用户密码的 MD5 摘要信息,未有完善的密码保护机制。开发者在生产环境中需自行设计合适的方案。
其它敏感信息存储:Demo 中使用到的 API 密钥以明文形式存储在 CVM 上,开发者需要注意对 CVM 的登录权限进行管控,以免密钥泄露。如果不再使用短视频 Demo,建议您重装系统以清理数据。