Skip to content
Qingfeng-YoloPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

22 Commits

Folders and files

Repository files navigation

MoodReel

一款基于 AI 分支续写的沉浸式互动短剧app


项目简介

MoodReel 是一款 Android 原生互动短剧播放器应用,核心亮点为 DramaPulse —— 在视频播放到特定高光时刻时,系统自动弹出互动分支,用户选择后由 AI 实时续写后续剧情(文字 + 文生图),实现"看剧 → 互动 → AI 续写"的闭环体验。

本项目采用 Jetpack Compose 声明式 UI + Hilt 依赖注入 + MVVM 架构,视频播放基于 Media3 ExoPlayer,网络层采用 Retrofit + OkHttp,所有 UI 状态通过 Kotlin Flow 驱动。 参考脚手架:


核心功能

功能 说明
沉浸式视频播放 基于 ExoPlayer 的全屏横屏播放器,支持手势控制(单击播放/暂停、双击快进/快退、长按倍速)
DramaPulse 互动 视频播放到预设高光时刻自动暂停,弹出分支选择面板
AI 分支续写 用户选择分支后,调用后端 AI 服务生成后续剧情文本 + 文生图海报
动态特效覆盖层 高光时刻触发 Canvas 动态特效(手电筒扫光、心跳脉冲),增强沉浸感
剧集列表浏览 展示剧集封面、标题、标签、简介,支持点击进入播放
Token 认证 基于 AccessToken / RefreshToken 双 Token 机制,自动刷新

技术栈

核心框架

类别 技术选型 版本 说明
编程语言 Kotlin 2.1.20 100% Kotlin,配合 K2 编译器
UI 框架 Jetpack Compose BOM 2026.03.01 声明式 UI,Material 3 组件
导航 Navigation Compose 1.1.0 类型安全路由 + 参数传递
依赖注入 Hilt + KSP 2.57.1 / 2.3.5 编译时依赖注入
异步处理 Kotlin Coroutines + Flow 1.10.2 响应式状态流

视频与媒体

类别 技术选型 版本 说明
视频播放 Media3 ExoPlayer 1.5.1 全功能播放器,支持手势、进度条、倍速
屏幕方向 Orientation Locker 1.1.2 强制横屏/竖屏切换
沉浸式 UI Accompanist System UI 0.37.2 隐藏系统导航栏/状态栏

网络与数据

类别 技术选型 版本 说明
HTTP 客户端 Retrofit + OkHttp 3.0.0 / 5.3.2 RESTful API 调用
JSON 序列化 Kotlinx Serialization 1.11.0 类型安全 JSON 编解码
图片加载 Coil 2.7.0 Compose 原生图片加载
本地存储 MMKV 1.3.9 高性能键值存储

开发工具

类别 技术选型 说明
日志 Timber 结构化日志输出
网络调试 Chucker 请求/响应抓包
内存检测 LeakCanary 内存泄漏检测

项目结构

MoodReel/
├── app/
│   └── src/main/java/com/qingfeng/moodreel/
│       │
│       ├── MainActivity.kt              # 应用入口
│       ├── Application.kt               # 初始化 Timber / MMKV / UltraSwipeRefresh
│       │
│       ├── core/                        # 核心公共层
│       │   ├── navigation/              # 导航框架(AppNavHost、AppNavigator)
│       │   │   ├── auth/               # 认证路由
│       │   │   ├── user/               # 用户路由
│       │   │   └── videoplay/          # 视频播放路由
│       │   ├── network/                 # 网络层(Retrofit + OkHttp)
│       │   ├── datastore/               # DataStore 本地存储
│       │   ├── model/                   # 数据模型(entity / state)
│       │   └── ui/component/video/     # 视频组件(VideoPlayer、VideoProgressBar)
│       │
│       └── feature/                     # 功能模块
│           ├── auth/                     # 登录模块
│           ├── user/                     # 用户中心
│           └── videoplay/                # 短剧视频播放(核心)
│               ├── view/                 # VideoPlayScreen(播放页入口)
│               ├── viewmodel/            # VideoViewModel(播放状态管理)
│               ├── navigation/           # VideoPlayGraph(Nav3 路由)
│               ├── component/            # 播放器 UI 组件
│               │   ├── player/          # 控制层(TopBar、BottomInfo、SideBar)
│               │   └── dramapulse/      # DramaPulse 互动组件
│               └── effect/              # Canvas 动态特效
│
├── build.gradle.kts
├── settings.gradle.kts
└── gradle/libs.versions.toml

快速开始

环境要求

  • Android Studio: Ladybug Feature Drop (2024.2.2) 或更高版本
  • JDK: 21
  • Gradle: 8.14
  • 最低 SDK: API 26 (Android 8.0)
  • 目标 SDK: API 36 (Android 16)

构建运行

# 克隆仓库
git clone <repository-url>
cd MoodReel

# 使用 Gradle Wrapper 构建
./gradlew assembleDebug

# 或直接通过 Android Studio 运行
# 1. File -> Open -> 选择项目根目录
# 2. 点击 Run 按钮(需连接设备或启动模拟器)

后端服务配置

项目需要配置后端 API 地址。在 NetworkModule.kt 中修改:

// app/src/main/java/.../core/network/di/NetworkModule.kt
private const val BASE_URL = "https://your-api-domain.com/"

后端需实现以下核心接口:

接口 方法 说明
/api/drama/discover GET 获取剧集列表
/api/drama/{id} GET 获取剧集详情
/api/drama/{id}/highlights GET 获取高光点配置
/api/drama/{id}/branch POST 提交分支选择,返回 AI 续写结果

DramaPulse 互动流程

用户进入播放页
      |
      v
ExoPlayer 加载视频并开始播放
      |
      v
监听播放进度(200ms 轮询)
      |
      v
匹配高光点(当前时间 ≈ 触发时间 ± 窗口容差)
      |
      v
自动暂停视频 + 显示分支选择面板
      |
      v
用户选择分支选项
      |
      v
调用 /api/drama/{id}/branch(携带上下文 + 选项)
      |
      v
后端 AI 生成续写文本 + 文生图海报
      |
      v
展示 AI 续写结果(文字 + 图片)
      |
      v
用户关闭结果面板,继续播放原视频

关键架构设计

1. 状态流驱动 UI

采用 双 StateFlow 分离高频/低频状态,避免不必要重组:

  • PlayerUiState(高频,~200ms):播放进度、缓冲状态、手势响应
  • DramaPulseUiState(低频,事件触发):互动面板显隐、分支数据、AI 结果

两者通过 combine(...).stateIn(WhileSubscribed(5000)) 合并为页面级状态。

2. 分层数据流

Presentation (Composable)
      |
      v
ViewModel (StateFlow + FlowResult)
      |
      v
Repository (业务逻辑 + 状态聚合)
      |
      v
DataSource (Retrofit Service 调用)
      |
      v
Backend API (REST)

3. 视频与高亮点同步

  • 统一使用 毫秒 精度时间戳
  • 配置 window_ms 容差窗口(默认 ±3000ms)
  • 单次高光点触发后 3 秒冷却期,防止重复触发
  • MMKV 本地去重,24 小时内同一高光点不再触发

工程难点

难点 解决方案
视频与高光点毫秒级同步 毫秒统一比较 +window_ms 容差 + 3s 冷却 + MMKV 24h 去重
高频播放进度 vs 低频互动状态 双 StateFlow 分离,combine + WhileSubscribed 按需合并
Canvas 动态特效性能 条件渲染(非触发时段直接 return)+BlendMode.Clear 挖空 + rememberInfiniteTransition 复用

开源许可

本项目基于 Apache License 2.0 开源。


Made with Jetpack Compose

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages