Skip to content

第三方直播/点播导入 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(已在白名单,面向服务端对接)

请求参数

参数类型必填说明
unionIdstring作者 Union ID,解析为本平台用户作为内容作者(authorId)
guidstring内容全局唯一 ID,作为幂等键:存在则更新,不存在则创建
titlestring内容标题
hlsUrlstring观众 HLS 播放地址
liveTypeint内容类型,1直播 2点播,默认按业务约定(见枚举)
thirdTypeint第三方来源,0本平台 1微赞 2微信 3抖音 4快手 5其他
categoryTypeint分类类型,业务自定义
describestring内容描述
coverUrlstring封面图片 URL
statusint直播状态,1预告 2直播中 3已结束 4回放 5已下线(见枚举)
startTimeTzint64直播开始时间,Unix 秒时间戳(如 1780000000)
endTimeTzint64直播结束时间,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(已在白名单,面向服务端对接)

请求参数

参数类型必填说明
guidstring内容全局唯一 ID,用于定位待更新的内容
statusint目标直播状态,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 / endTimeTzUnix 秒时间戳(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(),
    })
}