subtitle_content_callback
更新時間:2026-03-06 14:50:23
直播字幕即時回呼接入說明
當您在管理後台配置後,系統會在產生/彙總到一批字幕資料時,向該地址發起回呼請求,將字幕內容推送到您的服務端。
後台配置如圖:

callbackUrl 如何填寫
- 填寫內容:一個您方可公網存取的完整 URL,例如:
https://api.example.com/polyv/subtitles/callback - 請求方式:必須支援
POST - 資料格式:必須支援解析
multipart/form-data(表單方式,非 JSON Body) - 回應要求:建議在 10 秒內返回;返回任意 2xx 即視為成功(回應體內容不做強校驗)
回呼請求說明
請求方式
POST
Content-Type
multipart/form-data
超時與重試
- 超時:10 秒
- 重試:失敗會自動重試,最多 3 次
- 冪等建議:由於可能重試,請您按
roomId + sessionId + index(或其它業務唯一鍵)做去重/冪等處理
請求參數
| 參數名 | 必選 | 類型 | 說明 |
|---|---|---|---|
| roomId | 是 | string | 頻道號(房間號) |
| sessionId | 是 | string | 本場直播/會話 ID |
| subtitles | 是 | string | 字幕陣列的 JSON 字串(見下方欄位說明) |
| timestamp | 是 | number | 請求13位時間戳(毫秒,Date.now()) |
| sign | 是 | string | 簽名,用於鑑權與防篡改(見下方驗簽說明) |
subtitles 欄位說明
subtitles 是一個 JSON 字串,解析後為陣列,每個元素代表一條字幕片段物件。範例:
[
{
"text": "红不再是地产与金融的鼓舞,中环的键盘声中,一场重构全球资本格局的科技革命正在发生。",
"language": "Chinese",
"index": 0,
"relativeTime": 0,
"duration": 7610
}
]
字幕片段欄位如下(如存在新增欄位,請按「向後相容」原則忽略即可):
| 欄位名 | 必選 | 類型 | 說明 |
|---|---|---|---|
| text | 是 | string | 字幕文字 |
| language | 是 | string | 語言,當前支援(括號內為中文名稱):Chinese(中文)、English(英語)、Tagalog(他加祿語)、Thai(泰語)、Cantonese(粵語)、Korean(韓語)、Japanese(日語)、Indonesian(印尼語)、Vietnamese(越南語)、Malay(馬來語)、Portuguese(葡萄牙語)、Turkish(土耳其語)、Arabic(阿拉伯語)、Spanish(西班牙語)、Hindi(印地語)、French(法語)、German(德語)、Uyghur(維吾爾語) |
| index | 是 | number | 字幕下標(遞增,用於排序/冪等) |
| relativeTime | 是 | number | 相對時間(毫秒) |
| duration | 是 | number | 持續時長(毫秒) |
簽名(sign)生成與校驗
為保證回呼請求未被篡改,系統會在請求中攜帶 sign。您方可使用同樣演算法驗簽:
- 簽名金鑰(appSecret):
polyvlog - 簽名演算法:MD5(輸出大寫 16 進位)
- 參與簽名字段:除
sign本身外的所有請求字段(本回呼即roomId、sessionId、subtitles、timestamp)
簽名演算法步驟
- 取所有參數(包含
timestamp,不包含sign),按 key 的字典序升序排序(等同 JS 的Object.keys(data).sort())。 - 按順序拼接字串:
key + value(value 若為物件則JSON.stringify;本回呼裡subtitles本身是字串)。 - 在拼接串首尾各加一次金鑰:
appSecret + 拼接串 + appSecret - 對上一步結果做 MD5,得到十六進位字串,並轉為大寫,作為
sign。
Node.js 驗簽範例
const crypto = require('crypto');
function sortKeyAndValues(data) {
return Object.keys(data).sort().reduce((acc, key) => {
if (key === 'sign') return acc;
const v = data[key];
return acc + key + (v && typeof v === 'object' ? JSON.stringify(v) : String(v));
}, '');
}
function createApiSign(appSecret, data) {
const md5 = crypto.createHash('md5');
md5.update(`${appSecret}${sortKeyAndValues(data)}${appSecret}`, 'utf8');
return md5.digest('hex').toUpperCase();
}
// 验签
function verifySign(body) {
const { sign } = body;
const expect = createApiSign('polyvlog', body);
return String(sign).toUpperCase() === expect;
}
時間戳校驗建議(可選但推薦)
為防止重放攻擊,建議校驗 timestamp 與當前伺服器時間差不超過 30 分鐘(按毫秒)。
請求範例(curl)
下面範例展示了系統回呼請求的型態(multipart/form-data 表單字段):
curl -X POST 'https://api.example.com/polyv/subtitles/callback' \
-F 'roomId=123456' \
-F 'sessionId=test_session_id' \
-F 'subtitles=[{"text":"hello","language":"English","index":0,"relativeTime":0,"duration":1000}]' \
-F 'timestamp=1700000000000' \
-F 'sign=YOUR_SIGN'
回應要求
- 成功:請返回 HTTP 2xx(建議
200),回應體可為 JSON 或純文字 - 失敗:返回非 2xx 會被視為失敗並觸發重試
建議成功回應 JSON 範例:
{
"code": 200,
"status": "success",
"message": "ok",
"data": ""
}
常見接入問題
- 無法收到參數/參數為空:請確認後端是否支援解析
multipart/form-data(Express 預設的json/urlencoded中介軟體無法解析該格式)。 - 驗簽不通過:
- 確認
timestamp是毫秒; - 確認拼接順序為 key 升序;
- 確認 MD5 輸出需要轉大寫;
- 確認參與簽名的字段不包含
sign本身,且subtitles參與簽名時按「原始字串」處理。
- 確認
