产品手册
包名
we-livesdk· 版本1.0.0· UMD 全局window.LiveSDK
浏览器端直播 SDK:拉流播放、IM 聊天、互动、商品营销、运营弹框,挂到一个容器即起一个直播间。本手册覆盖全部对外能力——每个配置、方法、事件、模块、Store。
实现状态图例:✅ 已实现 · 🚧 占位未实现(Phase 2) · ⚠️ 待服务端验证(payload 推断)
| 能力 | 实现 | 状态 |
|---|---|---|
| 视频(直播 + VOD 回放) | 腾讯云 TCPlayer | ✅ |
| IM 聊天 | 腾讯 IM @tencentcloud/chat |
✅ |
| 实时信令 | LAPS WebSocket @zan/laps,断线降级 HTTP 轮询 |
✅ |
| 互动(点赞/礼物/分享) | 内置 app 模块 | ✅ |
| 商品列表 / 营销弹框 | entry 模块 | ✅(推送 payload ⚠️) |
| 运营浮层(券/抽奖/任务/讲解) | entry 模块 | ⚠️ |
| 主题 / i18n / 弹框 | 运行时 API | ✅ |
| 弹幕 / 水印 / 清晰度插件 | plugin | 🚧 |
兼容:iOS 12+ / Android 7+ / Safari 12+(ES2017)。UMD 经 Babel 转译,无原生 ESM 依赖。
pnpm add we-livesdkimport { LiveSDK } from 'we-livesdk'import 'we-livesdk/styles'
const sdk = new LiveSDK({ activityId: 'xxx', token: 'xxx', merchantId: 'xxx' })await sdk.mount('#live-container')sdk.on('ready', () => {})拉流地址与 IM 凭证由 SDK 凭
activityId + token + merchantId在mount()内自动认证拉取,无需手动传。仅用外部 IM 时才传tim。
UMD(裸 HTML)
Section titled “UMD(裸 HTML)”<link rel="stylesheet" href="we-livesdk/styles.css"><script src="we-livesdk/dist-umd/livesdk.umd.js"></script><div id="live-container"></div><script> new LiveSDK.LiveSDK({ activityId: 'xxx', token: 'xxx', merchantId: 'xxx' }).mount('#live-container')</script>构建:pnpm build:umd → dist-umd/{livesdk.umd.js, livesdk.iife.js, livesdk.esm.js},全局名 LiveSDK。
配置 SDKConfig
Section titled “配置 SDKConfig”new LiveSDK(config)。仅 activityId / token / merchantId 必填;缺失抛错。
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
activityId |
string |
✅ | 直播间 id | |
token |
string |
✅ | JWT 访问令牌 | |
merchantId |
string |
✅ | 商户 id | |
locale |
string |
'zh-CN' |
UI 语言,未知值告警回退 | |
entryModules |
AppEntryModuleId[] |
全部 | 启用哪些运营入口模块 | |
tim |
TIMConfig |
外部 IM 凭证;不传则认证自动注入 | ||
ws |
WSConfig |
WebSocket 配置;不配则降级 HTTP 轮询 | ||
wsUrl |
string |
⚠️ 已废弃,用 ws.url |
||
modules |
ModuleConfig[] |
全部 | 核心模块开关 { id, options? } |
|
appModules |
AppModuleConfigs |
全部启用 | 互动 app 模块开关 | |
layout |
LayoutConfig |
横竖屏 / Tab / 快捷评论 | ||
telemetry |
TelemetryConfig |
关 | 遥测上报,须显式 enabled:true(见 SPEC-TELEMETRY-LOGGING) |
|
sensitiveWords |
string[] |
客户端敏感词;空则不过滤(fail-open) |
TIMConfig:sdkAppId:number · userId:string · userSig:string · groupId:string
WSConfig:url:string · reconnectBaseDelay(1000) · reconnectMaxDelay(30000) · reconnectMaxAttempts(10) · heartbeatInterval(25000) · authTimeout(5000) · loginRetryMax(3)
WS 地址优先级:
ws.url→wsUrl(废弃) → 构建期VITE_WS_URL→ 内置测试兜底。线上务必显式传ws.url。
SDKOptions:origin?:string · saveUserInfo?:boolean · logLevel?:'silent'|'error'|'warn'|'info'|'debug'(默认 warn) · theme?:SDKTheme · i18n?:Partial<I18nMessages>
LayoutConfig:orientation?:'portrait'|'landscape'|'auto'(默认 auto,跟随后台 screenType) · chatTabs?:{key,label}[] · modulesOrder?:{chatOffset?} · shortcutComments?:(string|{text,delaySec?})[] · shortcutCommentsEnabled?:boolean(默认 true)
AppModuleConfigs:viewerCount · like · gift · goods · security,每项 { enabled?: boolean },默认全开。
AppEntryModuleId:'coupon' | 'lottery' | 'taskReward' | 'productList' | 'commentary' | 'goodsMarketing'
| 方法 | 签名 | 说明 |
|---|---|---|
| 构造 | new LiveSDK(config) |
创建实例,初始化模块(未拉流/未挂载) |
mount |
(target: string|HTMLElement) => Promise<void> |
认证 → 注入凭证 → 挂载 UI → 初始化模块 → emit ready |
destroy |
() => void |
emit destroy,卸载 UI、断 WS/IM、清定时器与本实例弹框 |
on / off / once |
(event, handler) => this |
事件订阅(类型安全) |
getEmitter |
() => IEventEmitter |
取底层 emitter |
use |
(plugin: IPlugin) => this |
注册插件 |
getModule |
<T>(id: ModuleId) => T|undefined |
取核心模块实例 |
getAppModule |
<T>(id: AppEntryModuleId) => T|undefined |
取运营入口模块实例 |
setTheme |
(theme: SDKTheme) => this |
增量改主题,已挂载即施色 |
setThemeColor |
(color: string) => this |
便捷 = setTheme({primaryColor}) |
setFontSize |
(size: string) => this |
便捷 = setTheme({fontSize}) |
modal |
(opts: ModalOptions) => Promise<boolean> |
打开本实例弹框,resolve 确认/取消 |
t |
(key: I18nKey) => string |
取本地化文案 |
openGoodsMarketing |
(numIid, opts?:{scoreGoods?}) => void |
打开营销弹框,按 numIid 惰性拉取 |
closeGoodsMarketing |
() => void |
关闭营销弹框 |
claimMarketingCoupon |
(couponId: number) => void |
领取营销弹框内优惠券 |
registerMarketingSection |
(kind, component) => void |
注册营销 section 渲染器(未知 kind 不抛错) |
只读属性:config(归一化配置)· i18n · stores(见下)。
mount()仅支持腾讯云直播(liveType=6),其它类型 emitauth.error中止;数据类降级 emitauth.warning不阻断。失败抛AuthError。
sdk.on(name, handler)。下表含 payload 类型。
核心 / 认证
Section titled “核心 / 认证”| 事件 | Payload | 触发 |
|---|---|---|
ready |
undefined |
mount 完成 |
destroy |
undefined |
destroy() |
error |
{code,message} |
全局错误 |
auth.success |
{streamUrl} |
认证成功 |
auth.error |
{code?,message} |
身份类失败,中止 mount |
auth.warning |
{reason,branch?:'configDetail'|'replayAddress'} |
数据类降级 |
| 事件 | Payload | 触发 |
|---|---|---|
live.status |
LiveStatus |
状态变更 |
live.orientation |
Orientation |
横竖屏确定 |
live.config |
Record<string,unknown> |
后台配置推送 |
live.thumb |
{thumb} |
点赞总数(LAPS 心跳/登录) |
live.startTime |
number |
预告计划开播时间(ms) |
live.coverImg |
string |
预告封面图 |
| 事件 | Payload | 触发 |
|---|---|---|
player.ready |
undefined |
可播 |
player.playing / player.pause |
undefined |
播放 / 暂停 |
player.waiting / player.stalled / player.recovered |
undefined |
缓冲 / 中断 / 恢复 |
player.firstframe |
undefined |
真首帧(一次性) |
player.ended |
undefined |
播放结束 |
player.error |
{code,message} |
播放错误 |
player.duration |
{duration} |
时长(VOD) |
player.timeupdate |
{currentTime} |
进度(节流 250ms,内部) |
player.replay.segment |
{index,total} |
回放切段 |
聊天 / IM
Section titled “聊天 / IM”| 事件 | Payload | 触发 |
|---|---|---|
chat.message |
ChatMessage |
新消息 |
chat.pinned |
ChatMessage|null |
置顶变更 |
chat.mute |
boolean|{muted} |
全员禁言开关 |
im.ready / im.reconnected |
undefined |
IM 就绪 / 重连 |
im.user_banned / im.user_kicked |
{userId,reason?} |
用户被禁言 / 踢出 |
im.error / im.net_error |
{code,message} |
IM 致命错误 / 网络断开 |
im.warning |
{code,message} |
缺凭证休眠告警 |
互动 / 用户 / 房间
Section titled “互动 / 用户 / 房间”| 事件 | Payload | 触发 |
|---|---|---|
interact.like |
{delta,count?,reaction?:ReactionKey} |
点赞帧 |
interact.like.total |
{total} |
点赞累计总数(角标权威源) |
interact.gift |
GiftPayload |
礼物 |
interact.cart / interact.share |
undefined |
底栏购物车 / 分享点击 |
interact.more |
{action?} |
底栏更多点击 |
user.join |
UserProfile |
用户进房 |
room.viewerCount |
{count} |
观看数(每 10s 轮询) |
| 事件 | Payload | 触发 |
|---|---|---|
goods.show |
GoodsItem |
展示商品卡 |
goods.hide |
{goodsId} |
隐藏商品卡 |
goods.list |
GoodsCardItem[] |
HTTP 首屏全量列表就绪 |
goods.buy |
{numIid,scoreGoods?} |
列表内点购买/兑换(host 接管下单) |
goods.config ⚠️ |
Record<string,unknown> |
商品配置推送 |
goods.open / goods.close |
undefined |
商品面板开 / 关 |
goods.marketing.open |
{numIid} |
营销弹框打开 |
goods.marketing.show |
MarketingDetail |
营销详情就绪 |
goods.marketing.error |
{numIid,message?} |
营销拉取失败(可重试) |
goods.marketing.close |
undefined |
营销弹框关闭 |
观看时长 / 应用模块
Section titled “观看时长 / 应用模块”| 事件 | Payload | 触发 |
|---|---|---|
duration.change |
{totalMs,seconds} |
每 5s |
duration.report |
{seconds,success} |
每 30s 上报结果 |
app.module.init / app.module.destroy |
{moduleId} |
app 模块生命周期 |
WebSocket
Section titled “WebSocket”| 事件 | Payload | 触发 |
|---|---|---|
ws.connected / ws.disconnected |
undefined / {reason?} |
连接 / 断开 |
ws.reconnect |
{attempts} |
重连尝试 |
ws.error / ws.auth_failed |
{code,message} |
WS 错误 / 认证失败 |
ws.room_status |
{status,reason?} |
5000 房间状态 |
ws.room_config |
Record<string,unknown> |
5010 房间配置 |
ws.kicked |
{roomId,reason?} |
1001 强制移出 |
ws.enter_message |
{roomId,data:{type,content}} |
5020 进场消息 |
ws.audience_change |
{agentId,roomId,eventType,eventData?} |
2020 观众变更(1禁言/2取消/3封禁/4踢出) |
ws.message / ws.server_time |
WSMessage / number |
原始帧 / 服务端时间(内部) |
ws.coupon_dispatch ⚠️ / ws.commentary ⚠️ / ws.goods_config ⚠️ |
Record<string,unknown> |
营销 / 讲解 / 商品推送 |
运营入口(⚠️ payload 推断)
Section titled “运营入口(⚠️ payload 推断)”| 事件 | Payload |
|---|---|
coupon.show / lottery.start / task.new / commentary.push |
Record<string,unknown> |
coupon.open|close · lottery.open|close · task.open|close · commentary.open|close |
undefined |
完整事件名常量见导出的
SDK_EVENTS。
type LiveStatus = 'not_started'|'ongoing'|'ended'|'banned'|'paused'|'error'|'expired'|'playback'// 对应服务端 102/101/103/104/105/106/107/108type ReactionKey = 'heart'|'ghost'|'qbox'|'rockhand'|'joystick'
interface ChatMessage { id; userId; userName; userAvatar?; content; timestamp type: 'text'|'system'|'pinned'|'enter'|'welcome'|'comment' template?; level?; levelName?; levelColor?; levelIcon?; welcomeTitle? // 等级/欢迎语扩展}interface GiftPayload { giftId; giftName; giftIcon?; userId; userName; count }interface GiftAnimation { userId; giftId; giftName; count; timestamp }interface UserProfile { userId; userName; avatar?; level? }interface GoodsItem { id; name; price; image?; url?; sellOut?; priceHidden? }interface LikeBurst { id: number; reaction: ReactionKey; count: number }interface SDKError { code: number; message: string }核心模块(getModule)
Section titled “核心模块(getModule)”sdk.getModule<T>(id),id ∈ liveRoom|player|im|interact|user|marketing|security。
player ✅
Section titled “player ✅”| 方法 | 说明 |
|---|---|
play() / pause() |
播放 / 暂停 |
setVolume(v) |
音量 [0,1] |
seek(time) |
跳转(仅 VOD) |
attachElement(el) |
绑定 video 元素 |
initStream(url) |
手动设流地址并起播 |
setReplayList(list) / getReplayList() |
注入 / 取回放分段 |
currentReplayIndex / isVodPlaying / isReplay |
只读 getter |
能力:直播 HLS/FLV(TCPlayer)+ VOD 多段回放(分段容错、整轮重试 3 次、15s 超时探测);直播错误指数退避重连。
| 方法 | 说明 |
|---|---|
sendTextMessage(text) |
发文本 |
sendCustomMessage({type,data?,description?}) |
发自定义消息 |
sendLikeMessage(count?) / sendGiftMessage(gift) |
发点赞 / 礼物 |
getHistoryMessages(count=20) |
拉历史 |
getOnlineCount() / getLikeCount() |
在线数 / 点赞数 |
getAdapter() |
取适配器(userSig 重登用) |
setCredentials(creds) |
注入 IM 凭证(init 前) |
凭证优先级:config.tim > 认证注入。缺凭证 → emit im.warning 并休眠。
interact ✅
Section titled “interact ✅”sendLike(count?) · sendGift(gift)(IM 不可用时降级本地 emit)。
user ✅
Section titled “user ✅”setUserId(id) · refreshUserSig(newSig)(userSig 过期重登)。
liveRoom ✅
Section titled “liveRoom ✅”无 host 方法;init() 内拉房间元数据并 emit live.* / room.viewerCount。状态码 101–108 → LiveStatus。
marketing 🚧
Section titled “marketing 🚧”showGoodsCard(goodsId) · hideGoodsCard() —— 占位空实现(Phase 2)。当前商品能力走 entry 模块 productList/goodsMarketing。
security 🚧
Section titled “security 🚧”setWatermark(text) · clearWatermark() —— 占位空实现(Phase 2)。
互动应用模块(appModules)
Section titled “互动应用模块(appModules)”构造期实例化,config.appModules.<key> = { enabled:false } 可关。默认全开。
| 模块 | key | 方法 / getter | emit |
|---|---|---|---|
| ViewerCount ✅ | viewerCount |
count · setCount(n) |
room.viewerCount |
| Like ✅ | like |
total · like(userId,delta=1) |
interact.like.total |
| Gift ✅ | gift |
queue · sendGift(p) · dequeue() |
interact.gift |
| Goods ✅ | goods |
visibleGoods · show(g) · hide(id) |
goods.show / goods.hide |
| Security ✅ | security |
isContentAllowed(c) · checkRateLimit(uid) |
— |
- Like:
live.thumb(服务端权威)+interact.like(增量)合并算总数。 - Security(app 层,区别于 core security 🚧):聊天限流 10 条/秒 + 非空校验。
- DurationTracker ✅(Player 内部,非 appModules):每 1s 累计、5s emit
duration.change、30s 上报duration.report;localStorage 持久 48h,支持watchKind: live|trailer|replay。
运营入口模块(entryModules)⚠️
Section titled “运营入口模块(entryModules)⚠️”WS 驱动的运营浮层,config.entryModules 选择启用(默认全开)。多数 open()/close() 仅发信号事件,UI 由集成方或内置组件渲染。
| 模块 | id | 命令式方法 | 主要 emit | 状态 |
|---|---|---|---|---|
| 优惠券 | coupon |
open() close() |
coupon.show/open/close |
⚠️ |
| 抽奖 | lottery |
open() close() |
lottery.start/open/close |
⚠️ |
| 任务奖励 | taskReward |
open() close() |
task.new/open/close |
⚠️ |
| 讲解 | commentary |
open() close() |
commentary.push/open/close |
⚠️ |
| 商品列表 | productList |
open()(惰性拉列表)close() |
goods.config/open/close/list/show/hide |
✅(推送 ⚠️) |
| 商品营销 | goodsMarketing |
经 SDK:openGoodsMarketing / closeGoodsMarketing / claimMarketingCoupon |
goods.marketing.* |
✅ |
⚠️ = payload schema 由 5010/6000/7000 LAPS 帧推断,测试环境无真实下行,上线前须以真实信令校验。
goodsMarketing为命令式(无 WS 订阅),其流程已实现。
Stores(sdk.stores)
Section titled “Stores(sdk.stores)”响应式状态,供自定义 UI 读取。_ 前缀为内部方法。
| Store | 暴露名 | 关键状态 | 公开方法 | 存在条件 |
|---|---|---|---|---|
| live | live |
status viewerCount title orientation startTime coverImg previewText endText countdownEnabled replayList trailerUrl kicked serverTime buyingFrenzy shortcutComments memberLevels · 派生 videoState isPortrait/isLandscape |
setRoomConfig(cfg) |
总是 |
| player | player |
isPlaying isPaused volume quality ready currentTime duration buffering error · 派生 isMuted progress hasError |
setVolume setQuality setControlsVisible toggleControls |
总是 |
| chat | chat |
messages(≤1000) pinned unreadCount muted userMuted userBanned banTips enterNotice historyLoaded |
sendMessage loadHistory setSelfId setSelfName setMuteStatus setWelcomeConfig |
总是 |
| interact | interact |
likeCount likeBursts(≤30) giftQueue |
sendLike consumeBurst(id) removeGift(id) |
总是 |
| user | user |
profile authenticated levelId · 派生 userId userName |
—(只读) | 总是 |
| goodsList | goodsList |
goods:Map · getter list floatCard |
applyChange(payload) |
productList 启用时 |
| marketing | marketing |
open numIid loading sections error |
setOpening setReady setError reset |
goodsMarketing 启用时 |
聊天敏感词:发送端命中 → 本地影子回显(仅本人可见);接收端命中 → 丢弃;无 matcher/异常 → fail-open 放行。
SDKTheme 字段(全可选,局部应用)映射到挂载容器上的 --live-* CSS 变量;默认值在 .livesdk-root(app.css)。
| 字段 | CSS 变量 | 默认 |
|---|---|---|
primaryColor |
--live-primary-color |
#ef4444 |
backgroundColor |
--live-bg-color |
#000000 |
overlayColor |
--live-overlay-color |
rgba(0,0,0,.6) |
chatBgColor |
--live-chat-bg-color |
rgba(0,0,0,.4) |
textColor |
--live-text |
white |
fontFamily |
--live-font-family |
系统字体栈 |
fontSize |
--live-font-size |
14px |
radius |
--live-radius |
0.5rem |
初始:options.theme;运行时:setTheme / setThemeColor / setFontSize(增量合并,已挂载即施色,未挂载缓存到 mount)。
config.locale(默认'zh-CN',未知值告警回退)。当前内置 locale:仅zh-CN。config.options.i18n: Partial<I18nMessages>覆盖部分文案。- 取值:
sdk.t(key)(仅接受已知I18nKey)。 - 文案分类(共 28 key):
status.*(状态浮层)·chat.*(输入/消息)·player.*(播放控件)·interact.*(底栏)·goods.*·coupon.label·room.viewerCount·task.entry·gift.sent·milestone.default·hotSell.cta。
sdk.modal(opts): Promise<boolean>(resolve true=确认 / false=取消/关闭)。归属本实例,destroy() 仅关本实例弹框。
ModalOptions:type?:'info'|'danger'(默认 info) · title? · content?(纯文本)/ html?({@html},自行防 XSS) · confirmText?(默认“确认”) · cancelText?(传了才显示取消按钮) · confirm?/cancel?:()=>void|Promise(异步,报错则阻塞关闭) · singleton?(true 先关其它弹框)。
sdk.use(new Plugin(opts))。IPlugin:{ id:string; install(sdk); uninstall?(sdk) }。子路径 we-livesdk/plugins。
| 插件 | 选项(默认) | 状态 |
|---|---|---|
DanmuPlugin |
speed(8) fontSize(14) opacity(.85) maxLines(3) |
🚧 占位 |
WatermarkPlugin |
text position(‘top-right’) opacity(.4) |
🚧 占位 |
DefinitionPlugin |
defaultQuality(‘auto’) qualityList([‘auto’,‘hd’,‘sd’]) |
🚧 占位 |
三个内置插件均为 Phase 2 占位实现,注册不报错但暂无实际效果。自定义插件按
IPlugin实现即可立即生效。
class AuthError extends Error { name = 'AuthError' statusCode?: number // HTTP / 业务码}mount() 认证失败抛 AuthError 并 emit auth.error,在 mount().catch() 捕获。SDK 仅导出此一个错误类。
包导出与构建
Section titled “包导出与构建”| 子路径 | 内容 |
|---|---|
we-livesdk |
LiveSDK、app 模块、SDK_EVENTS、AuthError、PollingFallback、BrowserTransport、bridgeLapsEvents、@zan/laps 转出(LapsAdapter LAPS_CMD ROOM_STATUS WATCH_EVENT 等) |
we-livesdk/components |
Svelte 组件 |
we-livesdk/stores |
Store 工厂 |
we-livesdk/plugins |
插件类 |
we-livesdk/types |
仅类型(SDKConfig SDKEventPayloads 等) |
we-livesdk/styles |
样式(Tailwind + --live-* 默认) |
we-livesdk/tailwind |
Tailwind 配置 |
UMD:入口 src/lib/umd-entry.ts(含样式)→ dist-umd/livesdk.{umd,iife,esm}.js,全局 LiveSDK,目标 ES2015 / Safari 12 / iOS 12。
实现状态总览
Section titled “实现状态总览”| 区块 | 状态 |
|---|---|
| 核心:mount/destroy、认证、事件、主题、i18n、弹框 | ✅ |
| 播放器(直播 + VOD 回放) | ✅ |
| IM 聊天、敏感词、禁言/封禁、欢迎语、历史 | ✅ |
| 互动 app 模块(viewerCount/like/gift/goods/security)+ 观看时长 | ✅ |
| 商品列表 / 营销弹框(命令式流程) | ✅ |
| WS 运营推送 payload(coupon/lottery/task/commentary/goods 推送) | ⚠️ 待服务端验证 |
core marketing / core security 模块方法 |
🚧 占位 |
| Danmu / Watermark / Definition 插件 | 🚧 占位 |
本手册是 SDK 对外契约的产品级真源,改动对外使用面必须同步:SDKConfig(及嵌套)字段、LiveSDK 公开方法、SDK_EVENTS/SDKEventPayloads 事件、构造/mount/destroy 行为、主题/i18n/modal/插件契约、src/lib/index.ts 导出、UMD 全局与构建产物。占位能力落地后须移除对应 🚧 标记。
| 日期 | 版本 | 变更 |
|---|---|---|
| 2026-06-26 | 1.0.0 | 初版:全量配置/方法/事件/模块/Store 覆盖;标注未实现(marketing/security core、3 插件 🚧)与待验证推送 payload(⚠️);以代码为真源,修正 README 旧示例 |