- 新增直播评论/上下文/礼物等 API 与回放组件 - 主播开播、云端推流配置与 streamer 校验 - 依赖与 Mongo 集合/种子更新 - 需求与调研文档补充 Made-with: Cursor
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
/** 主播工作台:当前登录用户对应的主播档案与开/关播 */
|
|
|
|
export type StreamerSelfData = {
|
|
streamerId: string
|
|
name: string
|
|
title: string
|
|
game: string
|
|
isLive: boolean
|
|
room: {
|
|
id: string
|
|
title: string
|
|
status: string
|
|
pullPlaybackUrl: string
|
|
} | null
|
|
}
|
|
|
|
export async function fetchStreamerSelf(): Promise<{ ok: true; data: StreamerSelfData } | { ok: false; status: number; message: string }> {
|
|
const res = await fetch("/api/streamer/me", { credentials: "include", cache: "no-store" })
|
|
const json = (await res.json().catch(() => ({}))) as {
|
|
success?: boolean
|
|
data?: StreamerSelfData
|
|
message?: string
|
|
}
|
|
if (!res.ok || !json.success || !json.data) {
|
|
return { ok: false, status: res.status, message: json.message ?? "无法加载主播档案" }
|
|
}
|
|
return { ok: true, data: json.data }
|
|
}
|
|
|
|
export type LiveCloudVendorId = "tencent" | "aliyun" | "qiniu" | "volcengine" | "generic"
|
|
|
|
export type LiveCloudUrlsPayload = {
|
|
vendor: LiveCloudVendorId
|
|
configured: boolean
|
|
streamName: string
|
|
expiresAt: string
|
|
setupHint?: string
|
|
docs?: { label: string; href: string }[]
|
|
push?: { rtmp?: string; srt?: string; note?: string }
|
|
play?: { hls?: string; flv?: string; rtmp?: string; note?: string }
|
|
}
|
|
|
|
export async function fetchStreamerCloudUrls(
|
|
vendor: LiveCloudVendorId,
|
|
ttlSec = 7200,
|
|
): Promise<{ ok: true; data: LiveCloudUrlsPayload } | { ok: false; message: string }> {
|
|
const res = await fetch(
|
|
`/api/streamer/live/cloud?vendor=${encodeURIComponent(vendor)}&ttl=${encodeURIComponent(String(ttlSec))}`,
|
|
{ credentials: "include", cache: "no-store" },
|
|
)
|
|
const json = (await res.json().catch(() => ({}))) as {
|
|
success?: boolean
|
|
data?: LiveCloudUrlsPayload
|
|
message?: string
|
|
}
|
|
if (!res.ok || !json.success || !json.data) {
|
|
return { ok: false, message: json.message ?? "无法获取云厂商地址" }
|
|
}
|
|
return { ok: true, data: json.data }
|
|
}
|
|
|
|
export async function postStreamerLiveAction(
|
|
action: "start" | "stop",
|
|
payload?: { title?: string; pullPlaybackUrl?: string | null },
|
|
): Promise<{ ok: boolean; message?: string; data?: Record<string, unknown> }> {
|
|
const res = await fetch("/api/streamer/live", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
credentials: "include",
|
|
body: JSON.stringify({ action, ...payload }),
|
|
})
|
|
const json = (await res.json().catch(() => ({}))) as {
|
|
success?: boolean
|
|
message?: string
|
|
data?: Record<string, unknown>
|
|
}
|
|
if (!res.ok || !json.success) {
|
|
return { ok: false, message: json.message ?? "操作失败" }
|
|
}
|
|
return { ok: true, data: json.data }
|
|
}
|