Video 模块是 Kira 的视频生成和播放工作区,支持文生视频 (t2v) 和图生视频 (i2v),与图片编辑器共享同一个 Generator 页面。
组件层次
核心组件
CanvasVideoPlayer
主视频播放器,位于 Generator 和 Rewind 页面。
components/feature/common/generator/canvas-video-player.tsx
| 功能 | 说明 |
|---|
| Video.js 播放器 | HTML5 视频播放 |
| 响应式布局 | 根据容器自适应尺寸 |
| 状态占位卡片 | pending/processing 旋转渐变边框、failed 红色边框 |
| VideoPlayerControls | 播放/暂停、进度条、音量、全屏 |
VideoPlayerControls
视频播放控制栏。
components/feature/common/generator/video-player-controls.tsx
| 控件 | 说明 |
|---|
| 播放/暂停 | 居中大按钮 + 底部栏按钮 |
| 进度条 | 拖拽定位,显示缓冲进度 |
| 时间显示 | MM:SS 格式 |
| 音量 | 滑块弹出(仅桌面端) |
| 全屏 | 浏览器全屏 API |
VideoSelector
视频生成配置面板,用户点击 VideoGenerate 按钮后弹出。
components/feature/common/generator/video-selector.tsx
| 配置项 | 说明 |
|---|
| 起始帧 | 上传/选择起始图片 (i2v 模式) |
| 提示词 | 文本描述动作和运动 |
| 比例 | 16:9 / 9:16 / 1:1 / auto |
| 时长 | 5 秒 / 10 秒 |
VideoGenerationCard
聊天消息中的视频生成状态卡片。
components/feature/common/chat/message/assistant/video-generation-card.tsx
| 状态 | 展示 |
|---|
| pending / processing | 旋转渐变边框 + loading 动画 |
| completed | 视频就绪 |
| failed | 错误信息 + 重试按钮 |
| insufficient_credits / plan | 升级/充值引导 |
底部媒体切换轮播,支持图片和视频混合展示。
components/feature/common/generator/media-selector.tsx
- 合并图片、视频和音频,按
createdAt 排序
- 视频缩略图带播放图标
- 生成中的视频显示旋转渐变边框
工具栏
PC 端
| 工具栏 | 位置 | 包含 |
|---|
PCVideoToolBar | 右侧边栏 | VideoGenerate 按钮 |
PCVideoTopToolBar | 顶部居中 | NewThread, Upload, VideoExport, Backward, Forward, Delete |
移动端
| 工具栏 | 位置 | 包含 |
|---|
MobileVideoToolBar | 底部 | AI 标签页: VideoGenerate;Basic 标签页: VideoExport, Backward, Forward, Delete |
移动端视频工具栏使用 AI/Basic 标签页切换,与移动端图片工具栏保持一致的交互模式。
视频生成流程
进入视频生成模式
用户点击 VideoGenerate 按钮 → editMode 设为 "video"
配置参数
VideoSelector 面板展开,用户设置提示词、比例、时长、起始帧
发送请求
确认后通过 function-call 格式发送 generateVideo 到 AI Agent
实时状态更新
WebSocket 推送视频状态变更,UI 实时更新
播放视频
生成完成后 CanvasVideoPlayer 自动加载播放
实时通知
通过 Centrifugo WebSocket 接收视频状态更新:
hooks/useVideoNotificationHandler.ts
| 消息类型 | 处理 |
|---|
video_status | 统一通知类型,根据 video.status 字段更新 versions 缓存、当前选中视频、消息列表 |
更新目标
- Versions 缓存 — TanStack Query 数据中的视频列表
- 当前选中视频 — Zustand store 中的
currentSelectVideo
- Messages 缓存 — 聊天消息列表中的视频生成卡片
状态管理
// store/poisson.ts
interface PoissonState {
currentSelectVideo?: Video; // 当前选中的视频
currentSelectMediaType: "image" | "video" | "audio"; // 当前媒体类型
editMode: EditMode; // 包含 "video" 模式
}
| 方法 | 说明 |
|---|
setCurrentSelectVideo(threadId, video) | 设置当前选中视频 |
getCurrentSelectVideo(threadId) | 获取当前选中视频 |
getCurrentSelectMediaType(threadId) | 获取当前媒体类型 |
setEditMode(threadId, "video") | 进入视频生成模式 |
视频数据模型
// models/version.ts
interface Video {
taskId: string;
videoId?: string | null;
thumbId?: string | null;
prompt?: string | null;
sourceImageId?: string | null;
duration: number;
ratio: string;
width?: number | null;
height?: number | null;
status: "pending" | "processing" | "completed" | "failed"
| "insufficient_credits" | "insufficient_plan";
errorMessage?: string | null;
createdAt: string;
blurhash?: string | null;
url?: string; // Signed URL(API 返回时生成)
thumbUrl?: string; // 缩略图 Signed URL
toolCallId?: string;
toolName?: string;
}
Hooks
| Hook | 文件 | 说明 |
|---|
useVideoPlayer | use-video-player.ts | Video.js 播放器状态 (play/pause/seek/volume) |
useSubmitVideoTask | useSubmitVideoTask.ts | 重新提交被阻塞的视频任务 |
useVideoNotificationHandler | useVideoNotificationHandler.ts | WebSocket 视频状态通知处理 |
Feed 视频
视频可以发布到用户 Feed:
| 平台 | 组件 | 路径 |
|---|
| PC | PCFeedVideo | components/feature/pc/feed/pc-feed-video.tsx |
| Mobile | MobileFeedVideo | components/feature/mobile/feed/mobile-feed-video.tsx |
使用原生 HTML5 <video> 播放,响应式适配容器宽高比。