从零搭建移动端数字人生成应用:React + Go + D‑ID 实战

从零搭建移动端数字人生成应用:React + Go + D‑ID 实战

本文记录一次从零到一的落地过程:在移动端界面中上传头像,选择"文本合成(TTS)"或"外部音频驱动",由后端调用 D‑ID 生成口播视频,前端轮询任务状态并展示结果。项目地址结构与关键代码已在文末附带定位,便于对照阅读与扩展。

背景与目标

  • 背景:需要一个轻量、可移植的 Demo,用于在手机端快速体验"数字人生成"完整链路。
  • 目标:
    • 前端拥有友好的移动端交互(上传、脚本选择、进度反馈、预览)。
    • 后端封装 D‑ID 接口并负责静态资源托管与安全校验。
    • 具备开发与生产两套可复用的运行方式。

演示效果:


视频链接:https://d-id-talks-prod.s3.us-west-2.amazonaws.com/google-oauth2|103255428553188602402/tlk_EWb-nMAMq7m3cGUFdybpb/1765430150108.mp4?AWSAccessKeyId=AKIA5CUMPJBIK65W6FGA\&Expires=1765516558\&Signature=2EPasLmubT8TSaIrj6Vc%2BAFDqPg%3D

总体架构

  • 前后端分离:前端 React + Vite,后端 Go + Gin
  • 访问路径:前端以相对路径 '/api' 发起请求,经 Vite 代理到本地后端。
  • 资源托管:后端将上传的文件落盘至 public/uploads 并静态暴露为 GET /static/uploads/<name>
  • 生成流程:上传头像 → 选择脚本 → 创建任务 → 轮询状态 → 展示视频

架构关键点:

  • 端口与代理:frontend/vite.config.ts:6-14 指定开发端口 5100,并将 /api 代理到 http://localhost:8088
  • CORS 与静态目录:backend/cmd/server/main.go:80-97,110-112 设置跨域与静态目录挂载。

技术选型与权衡

  • 前端:React 18Vite 5TypeScriptantd-mobileaxios。选择这些是为了快速搭移动端交互与良好开发体验。
  • 后端:Go 1.22Gingodotenv。强调简单、可读、易部署;godotenv 便于本地加载 .env
  • 第三方:D‑ID 作为视频生成服务,接口简单,但需要严格的 https 资源输入与鉴权策略。

关键数据流与接口设计

  • 上传图片:POST /api/uploadbackend/cmd/server/main.go:132-152
    • multipart/form-data 字段 file
    • 保存到 public/uploads,返回拼接的 url(受 PUBLIC_BASE_URL 影响)。
  • 创建任务:POST /api/talksbackend/cmd/server/main.go:153-227
    • 入参包含 imageUrltextvoice.langscriptType 等。
    • 重要校验:imageUrl/audioUrl 必须是公网 https 且可访问(后端会主动探测)。
  • 查询任务:GET /api/talks/:idbackend/cmd/server/main.go:228-241
    • 如配置了 DID_API_KEY,则直接透传 D‑ID 的原始返回(GetTalkRaw)。
  • 列表任务:GET /api/talksbackend/cmd/server/main.go:242-249)。
  • 健康检查:GET /api/healthbackend/cmd/server/main.go:113-119)。

鉴权策略与安全细节

  • D‑ID 鉴权头:
    • Basic:当 DID_API_KEY 包含冒号时,编码为 Basic <base64(user:pass)>
    • Bearer:否则为 Bearer <key>
    • 生成逻辑在 backend/internal/service/did.go:49-55
  • 安全建议:
    • 生产环境不应记录 Authorization 明文(当前代码会 log.Println("Authorization:", ah),见 backend/internal/service/did.go:63;建议关闭)。
    • GET /api/did/debug 仅用于开发验证鉴权类型(backend/cmd/server/main.go:120-131),生产建议移除或加权限控制。
    • 对上传文件建议增加类型校验与大小限制,避免存储滥用。

前端实现要点

  • 请求基址:frontend/src/services/http.ts:3-6 使用 '/api' 相对路径,利于网关统一代理。
  • 任务创建与轮询:
    • 创建:createTalkfrontend/src/services/did.ts:6-9)。
    • 轮询:Home.tsxuseEffect 每 2s 查询(frontend/src/pages/mobile/Home.tsx:92-106)。
  • 脚本模式:
    • text:用户输入文案,后端走 TTS Provider(可传 providervoiceId)。
    • audio:用户输入或采用默认音频 URL,需为公网 https(默认见 frontend/src/pages/mobile/Home.tsx:20)。

交互细节:

  • 创建前校验最小文案长度与音频 URL 的 https 前缀(frontend/src/pages/mobile/Home.tsx:42-66)。
  • 超时/异常反馈通过 Toast 统一处理(frontend/src/pages/mobile/Home.tsx:67-90)。

后端实现要点

  • 资源拼接:若 PUBLIC_BASE_URL 未设置,则退化为 http://<请求Host>backend/cmd/server/main.go:145-151)。
  • D‑ID 客户端:
    • 创建任务:CreateTalkWithOptsbackend/internal/service/did.go:71-110)。
    • scriptType='audio' 且未提供 audioUrl 时,优先读取 AUDIO_URL_DEFAULT,否则使用内置示例(backend/internal/service/did.go:84-94,默认链接见 backend/internal/service/did.go:91)。
    • 原始查询:GetTalkRawbackend/internal/service/did.go:136-147)。
  • 本地回退:当不满足公网 https 条件或未配置 DID_API_KEY 时,采用本地模拟完成(返回示例视频,backend/cmd/server/main.go:216-224)。

运行与部署

  • 开发:
    • 后端:cd backend && go run .\cmd\server\main.go
    • 前端:cd frontend && npm install && npm run dev;访问 http://localhost:5100
    • 健康检查:GET http://localhost:8088/api/health
  • 生产:
    • 后端构建:cd backend && go build -o server .\cmd\server\main.go;运行 ./server(Windows 为 server.exe)。
    • 前端构建:cd frontend && npm run build;部署 frontend/dist 到静态服务器。
    • 代理:使用网关将 /api 反向代理到后端,并设置后端 CORS_ORIGINS 为前端域名。
  • 隧道(可选):
    • cloudflared tunnel --url http://localhost:8088
    • 将生成的 https://xxxxx.trycloudflare.com 赋值给 PUBLIC_BASE_URL,用于上传文件的公网可达地址拼接与资源校验。

常见问题与排错

  • 图片不可访问/非 HTTPS:后端会返回错误,参考 backend/cmd/server/main.go:170-181
  • 音频不可访问/非 HTTPS:参考 backend/cmd/server/main.go:185-201
  • 未设置 DID_API_KEY:将走本地模拟路径(便于演示),参考 backend/cmd/server/main.go:216-224
  • 授权头泄漏:请移除 did.go 中对 Authorization 的日志记录,避免泄漏敏感信息(backend/internal/service/did.go:63)。

性能与扩展建议

  • 任务存储:当前为内存存储(Store 结构体,backend/cmd/server/main.go:52-78);生产建议改为持久化(数据库)并加入任务队列与重试机制。
  • Webhook:POST /api/webhook/did 为占位(backend/cmd/server/main.go:250-254);可扩展为落库、缓存、通知。
  • 上传安全:增加类型白名单、大小限制、病毒扫描;配合 CDN 进行加速与鉴权。
  • 观感优化:在前端增加进度提示、错误细节弹窗、视频封面裁剪等。

环境变量与配置

  • 示例文件:backend/.env.example:1-4
  • 关键变量:
    • DID_API_KEY:D‑ID 鉴权 Key;决定使用 Basic 或 Bearer(backend/cmd/server/main.go:120-131)。
    • PUBLIC_BASE_URL:上传文件返回 URL 的前缀,需为公网 https
    • PORT:后端监听端口,默认 8088
    • CORS_ORIGINS:允许的前端来源,默认 http://localhost:5100
    • AUDIO_URL_DEFAULT:音频模式下未提供 audioUrl 时的默认地址(backend/internal/service/did.go:84-94)。

代码定位索引

  • 路由与接口:backend/cmd/server/main.go:112-256
  • D‑ID 客户端:backend/internal/service/did.go:49-110,136-147
  • 前端代理:frontend/vite.config.ts:6-14
  • axios 基址:frontend/src/services/http.ts:3-6
  • 页面流程:frontend/src/pages/mobile/Home.tsx:37-106

总结一下哈

本文演示了一条清晰的落地路径:将第三方生成服务以后端为中心进行封装与治理,在前端提供面向移动端的简洁交互,并通过严格的 HTTPS 校验与隧道/网关方案确保资源可达与安全。后续可以在任务存储、回调处理、安全加固与观感优化方面继续演进,使之成为更稳健的生产级解决方案。

项目暂还没整理好准备开源,敬请等待!

相关推荐
泥菩萨^_^2 小时前
【每天认识一个漏洞】React 和 Next.js RCE漏洞
前端·javascript·react.js
一只爱吃糖的小羊3 小时前
React 避坑指南:“闭包陷阱“
前端·javascript·react.js
by__csdn3 小时前
大前端:定义、演进与实践全景解析
前端·javascript·vue.js·react.js·typescript·ecmascript·动画
资深web全栈开发3 小时前
Go语言从1.18到1.25版本功能更新详解
开发语言·后端·golang
周杰伦_Jay4 小时前
【字节开源Golang框架Eino】技术详解:架构原理+实战落地+避坑指南(附代码)
架构·golang·开源
teamlet5 小时前
多域名备案审核展示模板
golang
fruge5 小时前
React Fiber 架构详解:为什么它能解决页面卡顿问题?
前端·react.js·架构
互亿无线明明5 小时前
在 Go 项目中集成国际短信能力:从接口调试到生产环境的最佳实践
开发语言·windows·git·后端·golang·pycharm·eclipse
海上彼尚5 小时前
Go之路 - 5.go的流程控制
开发语言·后端·golang