90 天。一个团队。一套完整的类 TikTok 应用——从零仓库到 App Store 提交。
这是我们用 DTok 交付的全貌——一款开源 Flutter 短视频 + 直播平台的完整拆解。
🚀 DTok 是什么?
DTok 是一款基于 Flutter 的生产级短视频与直播应用。类比:TikTok + 斗鱼,但完全开源、可自部署、对开发者友好。
我们想证明:一个小团队,能在一个季度内交付一款功能完整的社交视频 App。这篇文章记录了我们构建的内容、关键架构决策以及全程总结的经验教训。
📦 已交付的核心功能
短视频信息流
- 无限垂直滑动信息流(类 TikTok)
- 自动播放 + 智能预加载
- 基于
video_player的硬件加速播放器 + 自定义控制器 - 点赞、评论、分享、收藏——全部乐观更新
直播功能
- 手机摄像头 RTMP 推流
- HLS 自适应码率低延迟播放
- 基于 WebSocket 的实时弹幕同步
- 虚拟礼物发送 + 金币体系
创作者工具
- 应用内录制(含滤镜和速度控制)
- 多片段剪辑时间线
- 字幕 + 音乐叠加
- 一键发布流程 + 自动生成封面
社交关系
- 关注 / 粉丝系统 + 实时信息流更新
- 用户主页(视频 / 点赞 / 收藏三栏)
- FCM 推送通知(新粉丝 & 互动)
- 基于互动信号的算法推荐"For You"页
变现层
- 应用内购买(IAP)金币
- 向直播间主播送礼
- 主播收益结算看板
- Stripe Connect 主播提现接入
🛠 技术栈
| 层级 | 技术选型 |
|---|---|
| 移动端 | Flutter 3.x(Dart) |
| 状态管理 | Riverpod + AsyncNotifier |
| 视频播放 | video_player + 自定义缓冲控制 |
| 直播 | RTMP 推流,HLS 拉流 |
| 后端 | Go(Gin)+ gRPC 微服务 |
| 实时通信 | WebSocket(弹幕)、Firebase(通知) |
| 存储 | MinIO(视频)、PostgreSQL(元数据) |
| CDN | Cloudflare R2 + Stream |
| CI/CD | GitHub Actions + Fastlane |
📐 救了我们的架构决策
1. Riverpod 替代 Bloc
我们在项目中途从 BLoC 切换到 Riverpod。AsyncNotifier 模式让异步数据操作的样板代码减少了约 40%。Provider 级别的状态隔离也让 Widget 测试变得简单得多。
2. 每个页面独立的 VideoController
我们没有使用全局视频播放器,而是让每个信息流 Item 自己管理控制器生命周期。这实现了滑动时正确的暂停/恢复逻辑,彻底消灭了大多数视频信息流实现中都会出现的"鬼音频"Bug。
3. 处处乐观 UI
每次点赞、关注、评论都会立即触发本地状态更新,无需等待服务端确认。我们构建了一个简单的回滚队列——服务端返回错误时 UI 自动回退。用户永远不需要等待。
4. 第 3 天就接入 Feature Flag
我们在第 3 天就接入了轻量级特性开关服务。这让我们可以把未完成的功能藏在 Flag 后面发布,并进行灰度上线。当直播功能在特定 Android OEM 机型上崩溃时,它两次救了我们。
📊 90 天的数据
- 47 个页面
- 12 个微服务(后端)
- 3200+ 次 Commit
- ~0 次崩溃(Crashlytics 验证)
- 中端 Android 冷启动时间:< 1.8 秒
💡 最大的经验教训
视频难。直播更难。 "能播视频"和"在 200+ 种 Android 机型上稳定播放视频"之间差距巨大。视频功能的工期预估请乘以 2。
实时同步是复杂度的藏身之处。 直播弹幕看似简单,直到你要处理重连、丢包下的消息排序、以及需要同步触达的礼物动画。
Flutter 在生产级视频 App 上已经真正成熟。 我们没有遭遇任何框架层面的 Bug,性能瓶颈始终是我们自己的代码。
🔓 开源
DTok 完全开源。欢迎探索代码库、给仓库点 Star,或在此基础上构建你自己的版本。
👉 GitHub: github.com/dtokapp/dtok
👉 演示地址: dtok.app
👉 Discord: 欢迎加入我们的开发者社区
如果你也在做视频赛道,或者对我们如何处理规模化架构感兴趣,欢迎在评论区留言——我很乐意针对任何技术层做深入探讨。
#Flutter #Dart #直播 #短视频 #开源 #移动开发