ReactViteAWSi18nZustand

使用 Vite + React 构建可通过 URL 分享的视频链式播放器(状态同步 / i18n / AWS 部署)

Sloth255
Sloth255
·3 min read·483 words

这是什么?

我构建了 Video Chain Player,这是一个 Web 应用,让你可以"将视频的必要片段串联起来,作为一个整体进行播放/分享"。

🔗 立即体验:https://video-chain-player.sloth255.com/

  • 剪辑视频,指定开始和结束时间
  • **串联(队列)**多个片段连续播放
  • 将串联状态编码到 URL 中,通过单个链接分享

非常适合创建"只展示这部分"的体验,例如健身流程、讲座重点片段或合集视频。

用户可以做什么

  • 创建片段:输入 URL/ID 和开始/结束时间来添加视频
  • 重新排序:通过拖放调整顺序
  • 预览:立即播放以验证时间点
  • 分享:复制 URL 并发送(接收者打开同一个串联)
  • 多语言:通过 URL 切换语言(例如 ?lang=ja

技术栈

领域 技术 备注
前端 React 18 + TypeScript UI 可维护性和类型安全
构建/开发服务器 Vite 快速 HMR,良好的开发体验
路由 React Router v6 通过路径 + 查询表达状态
状态管理 Zustand 轻量级,适合 URL 同步
拖放 UI @dnd-kit 实现重新排序
视频播放器 react-youtube(IFrame Player API) 快速嵌入播放
i18n i18next + react-i18next 翻译所有 UI 字符串
翻译加载 i18next-http-backend /public/locales/... 运行时获取
语言检测 i18next-browser-languagedetector 优先级:?lang= / localStorage / 浏览器
分析 GA4(gtag) SPA page_view + 自定义事件
托管 S3 静态网站 + CloudFront CDN 分发
IaC AWS SAM 模板 以代码方式管理 S3/CloudFront
CI/CD GitHub Actions + OIDC 无需长期密钥即可部署
测试 Vitest + Testing Library 测试组件/逻辑
代码规范/格式化 ESLint + Prettier 防止破坏性变更

架构与实现亮点

1) 将 Zustand 状态同步到 URL 实现即时分享

为了最大程度减少分享摩擦,我将串联的核心信息编码到 URL 中进行设计。

  • 无需服务端存储(无需账户)
  • 接收者只需打开链接即可重现相同状态

为了防止 URL 过长(会导致分享困难),我最小化了编码到 URL 中的信息。

  • 仅编码视频 idstart/end 时间
  • 标题和缩略图之后补充用于显示(防止 URL 膨胀)

最小化编码示例:

// 仅在 URL 中编码必要信息(id/start/end)
const minimalSegments = segments.map(({ id, start, end }) => ({ id, start, end }));

此外,分享链接不包含播放位置(正在播放哪个片段),确保"打开链接从头开始播放"。

2) 通过 HTTP 后端实现运行时 i18n 加载(构建无关)

最初,我考虑在构建时导入翻译 JSON,但为了更好地兼容静态托管和 CI,我选择了从 /public/locales/{{lng}}/translation.json 通过 HTTP 获取

  • 易于维护——只需添加语言文件
  • 构建过程不依赖翻译导入

3) 稳健处理各种 URL 变体(watch / Shorts / embed)

只支持"标准 URL"会很不方便,因此我扩展了输入模式:

  • 标准观看 URL
  • Shorts
  • 嵌入 URL

结果,"直接粘贴"的成功率提高了,批量注册也变得更加轻松。

4) 部署:S3 + CloudFront,CI:GitHub Actions(OIDC)

由于是静态网站,部署非常简单:

  • S3(静态托管)
  • CloudFront(CDN)

CI/CD 通过 GitHub Actions 自动化:构建 → S3 同步 → CloudFront 缓存失效。

关键点是 OIDC,无需存储长期密钥即可部署(在维持环境级别控制的同时最小化 Secrets)。

即使是静态网站,在前面加上 CloudFront 也能提供:

  • 通过缓存实现快速加载
  • 简便的 SPA 路由辅助(例如回退到 /

总结

Video Chain Player 专注于"片段 × 连续播放 × URL 分享",重点在于:

  • 将状态编码到 URL 中,最大程度减少分享摩擦
  • i18n + 语言 URL 同步,让接收者看到相同的语言
  • 包含部署和分析,使其达到"生产就绪"状态

从技术角度,我能够综合运用:

  • 使用 Vite 快速开发
  • 将 Zustand 状态同步到 URL 以提高可分享性
  • 使用 i18next 的 HTTP 后端实现轻量级翻译管理
  • 使用 OIDC 安全部署

一次性构建这个"完整运维栈"是此次开发的亮点。