外观
第三方直播/点播导入 API 文档
概述
第三方直播/点播导入接口用于把外部平台(微赞、微信、抖音、快手等)的直播或点播内容,以服务端对接(machine-to-machine)的方式上报到本平台,统一进入 live_content 内容库,复用本平台的评论 / 点赞 / 收藏 / 关注等互动体系。
- 导入接口(
POST /api/live/third)为异步入队处理:请求通过基本校验后立即入队并返回200,实际入库(创建或按guid更新)由后台消费者完成。 - 状态更新接口(
POST /api/live/third/status)为同步处理:直连 DB,立即更新并返回结果。
处理流程
text
第三方平台(微赞/微信/抖音/快手...)
│ POST /api/live/third(服务端对接)
▼
平台 HTTP API(apiGw :9050)
│ 基本校验通过 → 入队 → 立即返回 200
▼
直播导入队列(NATS / 内存兜底)
│ 后台消费者
▼
按 guid 幂等写入 live_content(创建 / 更新)
│
▼
统一内容库(复用评论/点赞/收藏/关注)鉴权
该接口已加入 JWT 白名单,无需用户登录 token,面向服务端对接。请通过网络层(内网调用 / IP 白名单 / 网关签名)保证调用方可信。
WARNING
该接口可写入内容库,请勿对公网无限制暴露;建议放在内网或加网关层鉴权。
导入接口
POST /api/live/third
上报一条第三方直播/点播内容。以 guid 为幂等键:已存在则更新,不存在则创建。
请求头
http
POST /api/live/third
Content-Type: application/json
# 无需 Authorization(已在白名单,面向服务端对接)请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
unionId | string | 是 | 作者 Union ID,解析为本平台用户作为内容作者(authorId) |
guid | string | 是 | 内容全局唯一 ID,作为幂等键:存在则更新,不存在则创建 |
title | string | 是 | 内容标题 |
hlsUrl | string | 是 | 观众 HLS 播放地址 |
liveType | int | 否 | 内容类型,1直播 2点播,默认按业务约定(见枚举) |
thirdType | int | 否 | 第三方来源,0本平台 1微赞 2微信 3抖音 4快手 5其他 |
categoryType | int | 否 | 分类类型,业务自定义 |
describe | string | 否 | 内容描述 |
coverUrl | string | 否 | 封面图片 URL |
status | int | 否 | 直播状态,1预告 2直播中 3已结束 4回放 5已下线(见枚举) |
startTimeTz | int64 | 否 | 直播开始时间,Unix 秒时间戳(如 1780000000) |
endTimeTz | int64 | 否 | 直播结束时间,Unix 秒时间戳 |
请求示例
json
{
"unionId": "u_1001",
"guid": "live_20260608_0001",
"liveType": 1,
"thirdType": 1,
"title": "测试直播",
"categoryType": 1,
"describe": "第三方导入的直播",
"coverUrl": "https://cdn.example.com/cover.jpg",
"hlsUrl": "https://cdn.example.com/live/0001.m3u8",
"status": 2,
"startTimeTz": 1780000000,
"endTimeTz": 1780003600
}响应
json
{
"code": 200,
"data": { "...回显请求体..." }
}INFO
返回 200 仅代表「已受理入队」,不代表已完成入库。入库结果可在「直播/点播管理」列表查看。
状态更新接口
POST /api/live/third/status
更新一条已导入内容的直播状态(如:预告 → 直播中 → 已结束)。以 guid 定位内容。该接口为同步处理(直连 DB,非入队):校验通过后立即更新并返回结果。
仅更新 status 字段;其余字段(标题、封面、HLS 等)不受影响。若传入 status 与当前一致,则直接返回 200,不做更新。
请求头
http
POST /api/live/third/status
Content-Type: application/json
# 无需 Authorization(已在白名单,面向服务端对接)请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
guid | string | 是 | 内容全局唯一 ID,用于定位待更新的内容 |
status | int | 是 | 目标直播状态,1预告 2直播中 3已结束 4回放 5已下线(见枚举) |
请求示例
json
{
"guid": "live_20260608_0001",
"status": 3
}curl
bash
curl --location --request POST 'http://127.0.0.1:9050/api/live/third/status' \
--header 'Content-Type: application/json' \
--data-raw '{
"guid": "live_20260608_0001",
"status": 3
}'INFO
status 取值见下方「字段枚举 · status 直播状态」。下线违规内容用 status=5。
字段枚举
liveType 内容类型
| 值 | 含义 | 说明 |
|---|---|---|
| 1 | 直播 | 第三方直播链接(HLS 拉流播放) |
| 2 | 点播 | 第三方点播视频(HLS 播放) |
thirdType 第三方来源
| 值 | 来源 | 说明 |
|---|---|---|
| 0 | 本平台 | 平台自有内容(非第三方导入时为 0) |
| 1 | 微赞 | 微赞直播 |
| 2 | 微信 | 微信直播 |
| 3 | 抖音 | 抖音直播 |
| 4 | 快手 | 快手直播 |
| 5 | 其他 | 其他第三方来源 |
status 直播状态
| 值 | 状态 | 说明 |
|---|---|---|
| 1 | 预告 | 直播尚未开始 |
| 2 | 直播中 | 正在直播 |
| 3 | 已结束 | 直播已结束 |
| 4 | 回放 | 结束后可回放 |
| 5 | 已下线 | 违规下线 / 不可见 |
INFO
点播(liveType=2)不依赖 status;直播 / 第三方直播按上表流转。下线违规内容用 status=5。
时间格式
startTimeTz / endTimeTz 为 Unix 秒时间戳(int64),即从 1970-01-01 UTC 起的秒数。无需关心时区,服务端按 UTC 秒解析。
| 写法 | 是否合法 | 说明 |
|---|---|---|
1780000000 | ✅ 合法 | 10 位秒级时间戳 |
0 | ✅ 合法 | 不传 / 0 表示不设置该时间 |
1780000000000 | ❌ 非法 | 13 位是毫秒,会被当成超大秒数解析错误 |
"1780000000" | ❌ 非法 | 字符串,应传数字(int64) |
INFO
注意是秒不是毫秒;若用 JS Date.now() 需除以 1000 再取整。
幂等与更新
guid 是内容全局唯一键。重复上报同一 guid 会更新已有记录(标题、封面、HLS、描述、status、起止时间等),不会产生重复内容。
首次创建时,unionId 会解析为本平台用户作为内容作者(authorId);若该 unionId 不存在,则该条上报会在后台消费阶段失败(不影响接口已返回的 200)。
错误码
| HTTP | 阶段 | message | 说明 |
|---|---|---|---|
| 200 | 接口 | ok | 已受理入队(不代表已入库) |
| 400 | 接口 | body unmarshal ... | JSON 格式错误,检查逗号/冒号/时间格式 |
| 400 | 接口 | title 不能为空 | title 缺失 |
| 400 | 接口 | unionId 不能为空 | unionId 缺失 |
| 400 | 接口 | hlsUrl 不能为空 | hlsUrl 缺失 |
| 400 | 接口 | guid 不能为空 | guid 缺失 |
| 500 | 接口 | 入队失败 | MQ 异常,检查服务端日志 |
| — | 消费 | unionId 不存在 | 后台入库阶段失败:作者未找到(接口仍已返回 200) |
| 400 | 状态接口 | guid 不能为空 | /api/live/third/status:guid 缺失 |
| 400 | 状态接口 | status 不能为空 | /api/live/third/status:status 缺失或 ≤0 |
| 400 | 状态接口 | 内容不存在 | /api/live/third/status:按 guid 未找到内容 |
| 500 | 状态接口 | update 失败 | /api/live/third/status:DB 更新异常,检查服务端日志 |
完整示例
curl
bash
curl --location --request POST 'http://127.0.0.1:9050/api/live/third' \
--header 'Content-Type: application/json' \
--data-raw '{
"unionId": "u_1001",
"guid": "live_20260608_0001",
"liveType": 1,
"thirdType": 1,
"title": "测试直播",
"categoryType": 1,
"describe": "第三方导入的直播",
"coverUrl": "https://cdn.example.com/cover.jpg",
"hlsUrl": "https://cdn.example.com/live/0001.m3u8",
"status": 2,
"startTimeTz": 1780000000,
"endTimeTz": 1780003600
}'Go
go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
const baseURL = "http://127.0.0.1:9050"
// LiveThirdReq 第三方直播/点播导入请求
type LiveThirdReq struct {
UnionId string `json:"unionId"`
Guid string `json:"guid"`
LiveType int32 `json:"liveType"`
ThirdType int32 `json:"thirdType"`
Title string `json:"title"`
CategoryType int32 `json:"categoryType"`
Describe string `json:"describe"`
CoverUrl string `json:"coverUrl"`
HlsUrl string `json:"hlsUrl"`
Status int32 `json:"status"`
StartTimeTz int64 `json:"startTimeTz"` // Unix 秒
EndTimeTz int64 `json:"endTimeTz"` // Unix 秒
}
func importLive(req LiveThirdReq) error {
body, _ := json.Marshal(req)
resp, err := http.Post(baseURL+"/api/live/third",
"application/json", bytes.NewReader(body))
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Println("status:", resp.StatusCode)
return nil
}
func main() {
start := time.Date(2026, 6, 8, 15, 4, 5, 0, time.UTC)
end := start.Add(time.Hour)
_ = importLive(LiveThirdReq{
UnionId: "u_1001",
Guid: "live_20260608_0001",
LiveType: 1,
ThirdType: 1,
Title: "测试直播",
HlsUrl: "https://cdn.example.com/live/0001.m3u8",
Status: 2,
StartTimeTz: start.Unix(),
EndTimeTz: end.Unix(),
})
}