Files
Hightube-report/midpresentation.md
2026-06-27 16:04:22 +08:00

574 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
marp: true
theme: default
size: 16:9
paginate: true
header: "Hightube 开源跨平台个人直播平台"
footer: "Highground-Soft | 中期汇报 (v1.0.0-Beta4.7) | 2026.05.05"
style: |
:root {
--ink: #0f172a;
--muted: #475569;
--soft: #64748b;
--line: rgba(15, 23, 42, 0.10);
--blue: #2563eb;
--cyan: #0891b2;
--gold: #d97706;
--paper: #fffdf8;
--paper-blue: #f4f8ff;
}
section {
position: relative;
padding: 56px 68px 48px;
font-family: 'Noto Sans CJK SC', 'Microsoft YaHei', sans-serif;
font-size: 28px;
line-height: 1.35;
color: var(--ink);
background:
radial-gradient(circle at top right, rgba(37, 99, 235, 0.16), transparent 28%),
radial-gradient(circle at bottom left, rgba(8, 145, 178, 0.12), transparent 24%),
linear-gradient(135deg, var(--paper) 0%, #f9fbff 45%, var(--paper-blue) 100%);
}
section::before {
content: "";
position: absolute;
inset: 22px;
border: 1px solid var(--line);
border-radius: 26px;
pointer-events: none;
}
header, footer { color: #64748b; font-size: 13px; letter-spacing: 0.04em; }
h1 { margin: 0 0 14px; font-family: 'Noto Serif CJK SC', 'STSong', serif; font-size: 52px; color: var(--ink); }
h2 { margin: 0 0 14px; font-size: 30px; color: var(--blue); font-weight: 700; }
h3 { margin: 0 0 8px; font-size: 22px; color: var(--ink); font-weight: 700; }
p, ul, ol { margin-top: 0; }
ul, ol { padding-left: 1.15em; }
li { margin: 0 0 6px; }
table { border-collapse: collapse; table-layout: fixed; }
th, td { padding: 5px 8px; vertical-align: top; word-break: break-word; }
strong { color: var(--blue); font-weight: 800; }
.accent { color: var(--blue); font-weight: 800; }
.gold { color: var(--gold); font-weight: 700; }
section.cover {
color: #e8eefc;
background: linear-gradient(135deg, #07111f 0%, #0f1f3d 42%, #1d4ed8 100%);
}
section.cover h1, section.cover h2, section.cover strong { color: #ffffff; }
section.cover .eyebrow { color: rgba(232, 238, 252, 0.78); font-size: 15px; font-weight: 700; letter-spacing: 0.16em; margin-bottom: 16px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.grid-5 { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }
.card {
background: rgba(255, 255, 255, 0.72);
border: 1px solid rgba(148, 163, 184, 0.18);
border-radius: 20px;
padding: 20px 22px;
box-shadow: 0 16px 38px rgba(15, 23, 42, 0.06);
}
.card.dark { background: rgba(15, 23, 42, 0.05); }
.metric-box { text-align: center; padding: 15px; border-radius: 15px; background: rgba(37, 99, 235, 0.05); }
.metric-value { font-size: 36px; font-weight: 800; color: var(--blue); display: block; }
.metric-label { font-size: 14px; color: var(--soft); }
.tag { display: inline-block; padding: 4px 10px; border-radius: 8px; font-size: 14px; font-weight: 700; background: rgba(37, 99, 235, 0.1); color: var(--blue); margin-right: 5px; }
.eyebrow { color: var(--soft); font-size: 15px; font-weight: 700; letter-spacing: 0.16em; margin-bottom: 8px; }
.closing { display: grid; place-items: center; height: 80%; text-align: center; }
.closing h1 { font-size: 72px; font-weight: 900; margin-bottom: 8px; color: var(--blue); }
.toc-item { display: flex; align-items: baseline; padding: 10px 0; border-bottom: 1px solid var(--line); }
.toc-num { font-size: 32px; font-weight: 900; color: var(--blue); min-width: 56px; }
.toc-text { font-size: 22px; }
.toc-sub { font-size: 15px; color: var(--soft); }
section.compact {
padding: 46px 58px 40px;
font-size: 24px;
line-height: 1.25;
}
section.compact h1 { font-size: 42px; margin-bottom: 10px; }
section.compact h3 { font-size: 19px; margin-bottom: 6px; }
section.compact .card { padding: 14px 16px; border-radius: 16px; }
section.compact .grid-2 { gap: 14px; }
section.compact .grid-3 { gap: 12px; }
section.compact li { margin-bottom: 4px; }
section.compact .tag { font-size: 12px; padding: 3px 8px; }
section.compact p[style],
section.compact ul[style],
section.compact ol[style],
section.compact table[style] { font-size: 14px !important; }
section.toc-slide h1 { font-size: 46px; margin-bottom: 10px; }
section.toc-slide .toc-item { padding: 7px 0; }
section.toc-slide .toc-num { font-size: 27px; min-width: 48px; }
section.toc-slide .toc-text { font-size: 19px; }
section.toc-slide .toc-sub { font-size: 13px; }
section.arch-slide table { font-size: 14px !important; }
section.arch-slide th,
section.arch-slide td { padding: 4px 6px; }
section.challenge-slide table { font-size: 16px; line-height: 1.26; }
section.challenge-slide th,
section.challenge-slide td { padding: 7px 9px; }
section.challenge-slide h1 { margin-bottom: 8px; }
section.plan-slide table { font-size: 14px !important; }
section.plan-slide .card ul { margin-bottom: 0; }
section.showcase-slide .card h3 { color: var(--blue); }
---
<!-- _class: cover -->
<!-- _paginate: false -->
<div class="eyebrow">Mid-term Progress Report</div>
# Hightube 中期汇报
## 成果与展望:构建私有化直播生态
<p class="lead">已实现从<strong>推流鉴权、多码率转码</strong>到<strong>多端互动观看</strong>的全链路闭环。</p>
<div style="margin-top: 40px; font-size: 18px;">
Highground-Soft 团队:程景愉、舒钰权、李俊友、张钊源<br />
当前版本:<strong>v1.0.0-Beta4.7</strong> | 项目状态:核心功能 100% 完成
</div>
---
<!-- _class: toc-slide -->
# 目录
<div style="display:grid; grid-template-columns: 1fr 1fr; gap: 12px 32px;">
<div class="toc-item">
<span class="toc-num">01</span>
<div>
<span class="toc-text">项目背景与目标</span>
<div class="toc-sub">为什么做 Hightube解决什么问题</div>
</div>
</div>
<div class="toc-item">
<span class="toc-num">02</span>
<div>
<span class="toc-text">中期成果概览</span>
<div class="toc-sub">五大功能域 + 研发数据统计</div>
</div>
</div>
<div class="toc-item">
<span class="toc-num">03</span>
<div>
<span class="toc-text">系统架构总览</span>
<div class="toc-sub">整体拓扑与核心数据流</div>
</div>
</div>
<div class="toc-item">
<span class="toc-num">04</span>
<div>
<span class="toc-text">关键技术突破</span>
<div class="toc-sub">流媒体转码、推流鉴权、弹幕系统</div>
</div>
</div>
<div class="toc-item">
<span class="toc-num">05</span>
<div>
<span class="toc-text">界面展示</span>
<div class="toc-sub">跨平台客户端与响应式布局</div>
</div>
</div>
<div class="toc-item">
<span class="toc-num">06</span>
<div>
<span class="toc-text">团队协作与工程化</span>
<div class="toc-sub">协作流程、成员贡献、代码规范</div>
</div>
</div>
<div class="toc-item">
<span class="toc-num">07</span>
<div>
<span class="toc-text">挑战、计划与演示</span>
<div class="toc-sub">踩坑记录、后续规划、现场演示流程</div>
</div>
</div>
</div>
---
# 项目背景与目标
<div class="grid-2">
<div class="card">
<h3>行业痛点</h3>
<ul style="font-size:17px;">
<li><strong>平台依赖性强</strong>:主流直播平台抽成高、规则不可控,创作者缺乏自主权。</li>
<li><strong>隐私风险</strong>:私有场景(教育、企业内训)数据流经公有云,存在合规隐患。</li>
<li><strong>部署门槛高</strong>RTMP + 转码 + Web 播放整套方案搭建复杂,个人开发者难以驾驭。</li>
</ul>
</div>
<div class="card">
<h3>Hightube 的答案</h3>
<ul style="font-size:17px;">
<li><strong>单二进制部署</strong>Go 编译为单一可执行文件,零依赖启动。</li>
<li><strong>全链路闭环</strong>:从推流→转码→分发→播放→互动,一气呵成。</li>
<li><strong>隐私可控</strong>:数据完全私有化,满足内网部署与合规需求。</li>
<li><strong>开源生态</strong>MIT 协议,社区可审计、可扩展。</li>
</ul>
</div>
</div>
<p class="lead" style="margin-top:16px;">目标:打造一个<strong>开箱即用、性能优异、生态开放</strong>的私有化个人直播基座。</p>
---
# 中期成果概览:五大功能域
<div class="grid-5">
<div class="card">
<div class="tag">01</div>
<h3>用户系统</h3>
<p style="font-size:15px">RBAC 权限控制<br/>Bcrypt 密码哈希<br/>JWT 令牌鉴权<br/>会话管理</p>
</div>
<div class="card">
<div class="tag">02</div>
<h3>直播核心</h3>
<p style="font-size:15px">RTMP 推拉流<br/>FFmpeg 多码率转码<br/>定时缩略图抓取<br/>流状态监控</p>
</div>
<div class="card">
<div class="tag">03</div>
<h3>实时互动</h3>
<p style="font-size:15px">WebSocket Hub<br/>弹幕遮罩渲染<br/>消息历史持久化<br/>心跳断线重连</p>
</div>
<div class="card">
<div class="tag">04</div>
<h3>管理后台</h3>
<p style="font-size:15px">系统监控指标<br/>SSE 实时日志流<br/>用户 CRUD 管理<br/>直播间状态面板</p>
</div>
<div class="card">
<div class="tag">05</div>
<h3>前端客户端</h3>
<p style="font-size:15px">Flutter 3.x 跨平台<br/>Windows / Android / iOS / Web<br/>多清晰度无缝切换</p>
</div>
</div>
<p class="lead" style="margin-top:16px;">累计交付 <strong>23</strong> 个功能模块,覆盖从注册到直播观看的<strong>完整业务生命周期</strong>。</p>
---
# 研发数据统计
<div class="grid-2">
<div class="card">
<h3>代码资产分布</h3>
<table style="width:100%; font-size:19px;">
<tr><th>模块</th><th>语言</th><th>源文件</th><th>行数</th></tr>
<tr><td>后端业务逻辑</td><td>Go</td><td>12</td><td>1,128</td></tr>
<tr><td>流媒体服务</td><td>Go</td><td>6</td><td>613</td></tr>
<tr><td>Flutter 跨平台</td><td>Dart</td><td>15</td><td>2,761</td></tr>
<tr><td>管理后台 Web</td><td>HTML/JS</td><td>5</td><td>789</td></tr>
<tr style="border-top: 2px solid var(--line);"><td><strong>总计</strong></td><td>-</td><td><strong>38</strong></td><td><strong>5,291</strong></td></tr>
</table>
</div>
<div>
<div class="grid-2" style="gap:10px;">
<div class="metric-box">
<span class="metric-value">18</span>
<span class="metric-label">Go 后端源文件</span>
</div>
<div class="metric-box">
<span class="metric-value">15</span>
<span class="metric-label">Dart 前端源文件</span>
</div>
<div class="metric-box">
<span class="metric-value">12s</span>
<span class="metric-label">缩略图抓取间隔</span>
</div>
<div class="metric-box">
<span class="metric-value">2</span>
<span class="metric-label">转码清晰度档位</span>
</div>
</div>
<div class="grid-2" style="gap:10px; margin-top:10px;">
<div class="metric-box">
<span class="metric-value">4</span>
<span class="metric-label">RESTful API 模块</span>
</div>
<div class="metric-box">
<span class="metric-value">30+</span>
<span class="metric-label">Git 贡献</span>
</div>
<div class="metric-box">
<span class="metric-value">4</span>
<span class="metric-label">支持平台数</span>
</div>
<div class="metric-box">
<span class="metric-value">60fps</span>
<span class="metric-label">弹幕渲染帧率</span>
</div>
</div>
</div>
</div>
---
<!-- _class: compact arch-slide -->
# 系统架构总览
<div style="text-align:center; margin-bottom:12px;">
<p style="font-size:16px; color:var(--soft); margin:0;">
OBS / 移动端推流 → <strong>RTMP Server</strong> → <strong>FFmpeg 转码管线</strong> → <strong>Go 业务后端</strong> → <strong>Flutter / Web 播放端</strong>
</p>
</div>
<div class="grid-2">
<div class="card">
<h3>流媒体层</h3>
<table style="width:100%; font-size:16px;">
<tr><td>推流协议</td><td><strong>RTMP</strong> (端口 1935)</td></tr>
<tr><td>转码引擎</td><td><strong>FFmpeg</strong> 子进程管线</td></tr>
<tr><td>输出档位</td><td>1080p 源码 + 720p 转码</td></tr>
<tr><td>Web 分发</td><td><strong>HTTP-FLV</strong> (flv.js 播放)</td></tr>
<tr><td>缩略图</td><td>每 12s 自动截取一帧</td></tr>
</table>
</div>
<div class="card">
<h3>业务层 (Go)</h3>
<table style="width:100%; font-size:16px;">
<tr><td>HTTP 框架</td><td><strong>Gin</strong> — 路由、中间件、CORS</td></tr>
<tr><td>数据库</td><td><strong>SQLite + GORM</strong> ORM 抽象</td></tr>
<tr><td>认证体系</td><td><strong>JWT</strong> 签发 + <strong>Bcrypt</strong> 哈希</td></tr>
<tr><td>实时通信</td><td><strong>Gorilla WebSocket</strong> Hub 模式</td></tr>
<tr><td>日志推送</td><td><strong>SSE</strong> 单向流至管理后台</td></tr>
</table>
</div>
</div>
<div class="card dark" style="margin-top:12px; padding:10px 22px;">
<p style="margin:0; font-size:15px;"><strong>部署方式</strong>Go 编译为单一静态二进制,内嵌 RTMP 模块与前端静态资源,<strong>单文件、零依赖</strong>即可启动完整服务。</p>
</div>
---
# 关键技术突破:流媒体与多端适配
<div class="grid-2">
<div class="card">
<h3>1. 动态转码管线 (FFmpeg)</h3>
<ul style="font-size:17px;">
<li><strong>自动触发</strong>:检测到推流到达即通过 <code>exec.CommandContext</code> 启动子进程。</li>
<li><strong>Context 管理</strong>:利用 Go <code>context.Context</code> 树状派生,推流断开时自动 <code>cancel()</code> 级联终止,杜绝僵尸进程。</li>
<li><strong>双档位输出</strong>:同时输出 Source (原始) 与 720p (转码) 两条流,互不阻塞。</li>
</ul>
</div>
<div class="card">
<h3>2. 多端播放兼容</h3>
<ul style="font-size:17px;">
<li><strong>原生端</strong>Flutter Windows / Android直连 <strong>RTMP</strong> 低延迟流,延迟约 12 秒。</li>
<li><strong>Web 端</strong>:通过 <strong>HTTP-FLV</strong> 重新封装 RTMP 流,前端使用 <code>flv.js</code> 解码播放。</li>
<li><strong>清晰度切换</strong>:播放器无刷新切换 Source ↔ 720p体验平滑。</li>
</ul>
</div>
</div>
---
<!-- _class: compact -->
# 关键技术突破:推流鉴权与弹幕系统
<div class="grid-2">
<div class="card">
<h3>3. 推流鉴权机制</h3>
<ul style="font-size:16px;">
<li>RTMP 推流请求携带 <code>stream_key</code>,在 <strong>URL 路径级</strong> 进行实时校验。</li>
<li>数据库验证 <code>StreamKey</code> 有效性与归属,<strong>推流路径与播放路径分离</strong>。</li>
<li>鉴权通过的推流方可触发转码管线;非法推流直接拒绝连接。</li>
</ul>
<div style="margin-top:6px;">
<div class="tag">Bcrypt</div> <div class="tag">JWT</div> <div class="tag">路径级鉴权</div>
</div>
</div>
<div class="card">
<h3>4. 高性能弹幕引擎</h3>
<ul style="font-size:16px;">
<li>服务端基于 <strong>Gorilla WebSocket</strong> 实现 Hub 模式:每个直播间一个独立 Room消息精准广播。</li>
<li>客户端使用 <strong>Stack + GlobalKey</strong> 回收弹幕 Widget避免频繁创建销毁。</li>
<li>支持 <strong>5 行轨道</strong>并发滚动,<strong>心跳检测</strong>自动断线重连,稳定保持 60fps。</li>
<li>弹幕层包裹 <code>IgnorePointer</code><strong>不拦截</strong>底层视频控制栏触摸事件。</li>
</ul>
<div style="margin-top:6px;">
<div class="tag">WS Hub</div> <div class="tag">心跳检测</div> <div class="tag">60fps</div>
</div>
</div>
</div>
<div class="card dark" style="margin-top:12px; padding:10px 22px;">
<p style="margin:0; font-size:15px;"><strong>管理工具</strong>:自研嵌入式 Web 控制台,通过 <strong>SSE</strong> 实时推送系统日志与运行指标,无需额外依赖。</p>
</div>
---
<!-- _class: showcase-slide -->
# 界面展示:跨平台体验亮点
<div class="grid-3">
<div class="card" style="text-align:center;">
<h3>响应式网格</h3>
<p style="font-size:16px;">直播间列表采用自适应网格布局,不同屏幕尺寸自动调整列数,保持视觉一致性。</p>
</div>
<div class="card" style="text-align:center;">
<h3>动态缩略图</h3>
<p style="font-size:16px;">后端每 12s 自动截取一帧封面,前端定时轮询,用户无需进入即可看到实时画面。</p>
</div>
<div class="card" style="text-align:center;">
<h3>实时状态徽标</h3>
<p style="font-size:16px;">"直播中" 角标实时同步房间活跃状态,观众一目了然。</p>
</div>
</div>
<div class="grid-2" style="margin-top:16px;">
<div class="card">
<h3>Flutter 跨平台一致性</h3>
<p style="font-size:16px;">基于 Flutter 3.x 自绘引擎Windows / Android / iOS / Web 四端共用一套 UI 代码,平台间视觉偏差 &lt; 5%。</p>
</div>
<div class="card">
<h3>播放器细节</h3>
<p style="font-size:16px;">支持横竖屏自动切换、双击暂停、进度条拖拽、亮度/音量手势调节(移动端),清晰度菜单一键切换。</p>
</div>
</div>
---
<!-- _class: compact -->
# 团队协作与工程化实践
<div class="grid-2">
<div class="card">
<h3>标准协作流程</h3>
<ul style="font-size:16px;">
<li><strong>API 契约先行</strong>:前后端联调前先落定 RESTful 接口文档,消除理解歧义,显著降低集成摩擦。</li>
<li><strong>Feature Branch 工作流</strong>:功能分支 → PR → Code Review → 合并main 分支始终保持可发布状态。</li>
<li><strong>自动化规范</strong>:后端强制 <code>gofmt</code> 格式化;前端配置严格 <code>analysis_options.yaml</code> — 拒绝未使用的 import / 变量。</li>
</ul>
</div>
<div class="card">
<h3>成员与分工</h3>
<table style="width:100%; font-size:15px;">
<tr><td><strong>程景愉</strong></td><td>后端核心开发、流媒体架构设计与 FFmpeg 转码管线</td></tr>
<tr><td><strong>舒钰权</strong></td><td>RESTful API 开发、数据库建模、管理后台</td></tr>
<tr><td><strong>李俊友</strong></td><td>Flutter 播放器核心、WebSocket 实时互动模块</td></tr>
<tr><td><strong>张钊源</strong></td><td>跨平台 UI 适配、Android 端推流联调、项目文档</td></tr>
</table>
</div>
</div>
<p class="lead" style="margin-top:14px;">经过 <strong>30+</strong> 次审查与合并,形成稳定的迭代节奏。</p>
---
<!-- _class: compact challenge-slide -->
# 遇到的挑战与解决方案
| 挑战 | 问题描述 | 解决方案 | 结果 |
| :--- | :--- | :--- | :---: |
| **RTMP 鉴权** | 默认 RTMP 无认证,任何人可推流 | 路径解析 `stream_key` + 数据库实时验证 | ✅ |
| **FFmpeg 僵尸进程** | 推流断开后子进程未回收,内存泄漏 | `context.Context` 树状管理 + `defer cancel()` | ✅ |
| **Web 端无法播放** | 浏览器不支持 RTMP 直连 | 增加 HTTP-FLV 封装层,前端接入 `flv.js` | ✅ |
| **弹幕拦截触控** | 弹幕层遮挡视频控制栏 | `IgnorePointer` 穿透弹幕层,保留交互 | ✅ |
| **跨平台 UI 偏差** | 不同平台渲染效果不一致 | 统一 Material Design 3 规范 + 响应式断点 | ✅ |
| **SSE 连接泄漏** | 管理后台长时间挂机导致连接堆积 | 引入心跳超时机制 + 客户端自动重连 | ✅ |
---
<!-- _class: compact plan-slide -->
# 后续计划:迈向 AI 时代
<div class="grid-2">
<div class="card">
<div class="tag">核心创新</div>
<h3>AI VTuber 互动引擎</h3>
<ul style="font-size:16px;">
<li>对接大语言模型 (LLM),直播间弹幕自动触发 AI 上下文回复。</li>
<li>结合 <strong>TTS 语音合成</strong> 与 <strong>Live2D 虚拟形象</strong>,实现无人值守的智能助播。</li>
<li>支持自定义角色人设与回复风格,丰富直播内容层。</li>
</ul>
</div>
<div class="card">
<div class="tag">体验优化</div>
<h3>国际化与鲁棒性</h3>
<ul style="font-size:16px;">
<li>接入 Flutter ARB 国际化框架,首期中/英双语支持。</li>
<li>移动端手势控制:亮度(左半屏)、音量(右半屏)滑动调节。</li>
<li>后端补充核心路径单元测试,覆盖率目标 ≥ 70%。</li>
<li>引入 Docker 容器化部署,降低运维门槛。</li>
</ul>
</div>
</div>
<div style="margin-top:12px;">
<table style="width:100%; font-size:17px;">
<tr><th style="width:25%;">里程碑</th><th style="width:30%;">时间</th><th>交付物</th></tr>
<tr><td><strong>Beta 4.7</strong></td><td>2026.05 ✅</td><td>核心功能 100%,中期汇报</td></tr>
<tr><td><strong>AI 模块初版</strong></td><td>2026.05 底</td><td>LLM 接口联调 + TTS 集成</td></tr>
<tr><td><strong>v2.0 正式版</strong></td><td>2026.06 初</td><td>i18n、Docker、AI VTuber、单元测试</td></tr>
</table>
</div>
---
<!-- _class: compact -->
# 演示流程预览
<div class="grid-2">
<div class="card">
<h3>演示主线(约 3 分钟)</h3>
<ol style="font-size:16px;">
<li><strong>零配置启动</strong>:一条命令启动,服务立即就绪。</li>
<li><strong>Flutter 端注册</strong>:创建账号,自动开通专属直播间。</li>
<li><strong>OBS 推流</strong>:配置 RTMP 地址 + StreamKey开启 1080p 推流。</li>
<li><strong>多端观看</strong>PC / 手机 / 浏览器同时拉流,对比延迟。</li>
<li><strong>弹幕互动</strong>:移动端发送弹幕,各端实时同步显示。</li>
<li><strong>管理后台</strong>SSE 实时日志滚动,指标面板刷新。</li>
</ol>
</div>
<div class="card">
<h3>演示重点</h3>
<ul style="font-size:17px;">
<li><strong>低延迟</strong>RTMP 直连实现秒级观看延迟。</li>
<li><strong>平滑切换</strong>Source / 720p 清晰度无刷新切换。</li>
<li><strong>实时同步</strong>:弹幕、日志、状态多端一致。</li>
<li><strong>全链路</strong>:从推流到播放,一条命令、零外部依赖。</li>
</ul>
</div>
</div>
---
<div class="closing">
<div>
<p class="eyebrow">Thank You</p>
<h1>感谢聆听</h1>
<p style="font-size:24px; margin: 16px 0 8px;"><strong>Hightube</strong> — 私有化直播基座建设阶段性完成</p>
<p style="font-size:18px; color: var(--soft); margin: 0 0 24px;">欢迎老师指正Q & A</p>
<p style="font-size:16px;">开源地址:<strong>https://git.nudt.space/Highground-Soft/Hightube</strong></p>
</div>
</div>