部分
技术
真实的Dueli技术栈分为两层:通俗解释和工程视角。
本页面解释了 Dueli 实际使用的技术,分为两层:面向所有人的通俗解释和面向专业人士的工程视角。除非当前代码使用了某项技术,否则不会将其列出。
通俗解释
Dueli 在 Cloudflare 的全球网络上通过浏览器运行。两位参赛者在其设备之间进行实时视频通话(WebRTC 点对点);当网络阻塞直接路径时,TURN 中继会帮助建立连接。
比赛期间,浏览器将两个摄像头画面合并在一个画面中,并将其录制为5秒的短片段。这些片段在生成后立即上传,可以按顺序播放,比赛结束后会组合成完整的回放。
录制的比赛可以下载为 MP4 文件。当需要转换录制文件时,转换在访问者的浏览器内使用 FFmpeg.wasm 运行,因此文件不会发送到外部转换服务。
平台数据存储在 D1 中,页面和 API 使用 Hono 和 TypeScript 在 Cloudflare 上构建,界面使用 Tailwind CSS。实时更新通过 SSE 和轮询到达。
面向工程师
运行时:Cloudflare Pages/Workers 配合 Hono 4 和 TypeScript。D1(SQLite)是数据库。Vite 构建 Worker 包,Tailwind CSS 4 美化界面,esbuild 打包浏览器入口点。
实时媒体:浏览器 RTCPeerConnection 在主机和对手之间传输 WebRTC。ICE 服务器通过 GET /api/signaling/ice-servers 按会话发放;Cloudflare Calls TURN(TURN_TOKEN_ID 和 TURN_API_TOKEN)或自托管 coturn(TURN_URL 和 TURN_SECRET)可以中继,若两者均未配置,则回退到仅 STUN 模式。
录制:一个 canvas 合成器绘制两个画面,MediaRecorder 每5秒输出一个片段。主机在每个片段注册于 POST /api/chunks/register(一个与比赛、序列和字节上限绑定的短期一次性密钥)后上传,通过 GET /verify 验证,并报告 POST /receipt。播放时读取 GET /api/chunks/playlist/:id,现有的 finalize 步骤生成 VOD。
下载:@ffmpeg/core 0.12.10 在自托管的浏览器 worker 中运行以进行 MP4 转换,对已是 MP4 兼容的录制文件采用结构性重新封装路径。进度和内存限制在客户端服务中处理。
实时性:通过 GET /api/sse 的 SSE 携带实时更新,信令使用 HTTP 轮询;生产环境路径不使用 WebSocket。
质量:Vitest 覆盖单元和 UI 合约,Playwright 覆盖端到端浏览器流程。Markdown 文档使用 marked 渲染,PostCSS 与 Autoprefixer 完成CSS处理流程。
本仓库中的技术栈
- Cloudflare Pages / Workers 托管和服务器运行时
- Cloudflare D1 (SQLite) 应用数据库
- Hono 4 HTTP 路由、页面和 API
- TypeScript 5 服务器和客户端的类型化源码
- Tailwind CSS 4 + PostCSS + Autoprefixer 界面样式和 CSS 处理流程
- Vite 7 + esbuild Worker包和浏览器入口点
- WebRTC (RTCPeerConnection) + TURN/STUN 参与者之间的实时音频和视频
- Canvas合成器 + MediaRecorder 浏览器内5秒的录制片段
- FFmpeg.wasm (@ffmpeg/core 0.12.10) 浏览器内MP4转换和下载
- marked 17 托管文档的Markdown渲染
- Vitest 5 单元和UI测试套件
- Playwright 端到端浏览器测试
- Wrangler 4 Cloudflare开发和部署工具
- SSE + HTTP轮询 媒体路径外的实时更新
此列表仅限于package.json和仓库实际包含的内容。这是一个技术描述,而非合作伙伴关系或认可声明。