# video-workflow
公司内部使用的 AI 短视频创作与运营工作台,面向抖音内容生产场景,把选题分析、脚本与素材生成、视频合成、账号运营和内容资产管理集中到一套工作流中。
> `package.json` 中的包名仍为 `tik-tok`,本文统一使用仓库与产品名 `video-workflow`。
## 功能特性
### 内容生成
- 数字人合成:形象素材、脚本与音色生成口播视频。
- 图片生成:根据提示词、风格和比例生成图片素材。
- 文生视频:根据提示词、比例和时长生成视频。
- 图生视频:使用图片、提示词和时长生成动态视频。
- 动作迁移:使用角色图片和参考动作视频生成角色动画。
- 素材合成视频:将多张图片、主题和音色组合为讲解视频。
- 主题生视频:从主题出发,完成脚本、配图、配音和视频合成。
- 批量生产:基于主题生视频模板串行执行多个生产任务。
### 内容运营与资产
- 抖音视频搜索、链接分析、爆款分析和逐字稿处理。
- 博主监测、选题池、日报、分析历史和发布复盘。
- IP 操盘工作台:账号定位、证据分析、内容方向、脚本和发布闭环。
- 我的创作、素材库、模板库、任务管理和视频管理。
- AI 助手、语音合成、官方音色选择和音色复刻。
### 账号与数据
- 使用手机号验证码自动登录或注册。
- 生成、合成和训练类操作可接入积分预扣、确认和失败退款流程。
- 用户数据按 Parse 用户 `objectId` 隔离。
- 草稿和部分浏览器数据使用 IndexedDB,并保留 localStorage 回退。
- 业务主数据和文件资产可通过 fmode 云函数持久化。
## 技术栈
### 前端
- Angular `21.2`
- TypeScript `5.9`
- RxJS `7.8`
- Standalone Components、Signals
- FFmpeg WebAssembly:`@ffmpeg/ffmpeg`、`@ffmpeg/core`
- Vitest、Playwright
### 本地后端
- Node.js
- Express `4.21`
- multer、cors、axios、undici
- 系统 FFmpeg / ffprobe
- 可选 OpenAI Whisper CLI
### 外部服务
- fmode Parse、云函数和 APIG
- 即梦 / 火山引擎视频、图片与语音能力
- 抖音数据网关 / TikHub
- 七牛云对象存储
- LLM / Gemini 代理
- Quickly 一键成片
## 环境要求
必需:
- Node.js:仓库暂未在 `package.json` 中限定最低版本。
- npm:仓库声明的包管理器版本为 `11.6.1`。
按功能需要:
- FFmpeg 和 ffprobe:本地音频提取、视频下载处理及服务端视频合成需要,并且命令必须已加入 `PATH`。
- Whisper CLI:仅本地 Whisper 转写功能需要。
- Microsoft Edge:当前 Playwright 配置使用 `msedge` 通道。
- PowerShell、华为云 `obsutil` 和 `hcloud`:仅执行内部部署脚本时需要。
检查本机环境:
```bash
node --version
npm --version
ffmpeg -version
ffprobe -version
```
如需本地 Whisper:
```bash
pip install openai-whisper
whisper --help
```
## 安装步骤
1. 进入项目目录。
```bash
cd video-workflow
```
2. 安装依赖。
```bash
npm install
```
3. 创建本地环境变量文件。
PowerShell:
```powershell
Copy-Item .env.example .env
```
Bash:
```bash
cp .env.example .env
```
4. 根据需要填写 `.env`。不要提交真实 token、密钥或 session token。
5. 同时启动 Angular 前端和 Express 后端。
```bash
npm run dev
```
6. 打开 。
可使用后端健康检查确认本地服务是否启动:
```text
http://localhost:3000/api/health
```
## 配置说明
`server.js` 启动时会读取仓库根目录的 `.env`。已有系统环境变量优先,不会被 `.env` 覆盖。
完整模板见 [`.env.example`](./.env.example)。以下是主要配置:
### 基础服务
| 变量 | 默认值/用途 |
|---|---|
| `PORT` | Express 端口,模板值为 `3000`。 |
| `PARSE_API_HOST` | Parse 与 fmode API 主机。 |
| `PARSE_APP_ID` | Parse Application ID。 |
| `PARSE_BASE_URL` | fmode 云函数调用地址。 |
### 即梦生成
| 变量 | 用途 |
|---|---|
| `JIMENG_BASE_URL` | 即梦生成代理地址。 |
| `JIMENG_TOKEN` | 图片、视频、数字人和动作迁移等生成请求的凭证。 |
### 抖音数据与转写
| 变量 | 用途 |
|---|---|
| `DOUYIN_API_BASE_URL` | 抖音数据网关地址。 |
| `DOUYIN_API_TOKEN` | 抖音数据网关 token。 |
| `VOC_TOKEN` / `VOC_SOCIAL_TOKEN` | 抖音数据网关的兼容 token。 |
| `TIKHUB_BASE_URL` / `TIKHUB_TOKEN` | 明确直连 TikHub 时使用。 |
| `IFLYTEK_GATEWAY_BASE_URL` | 逐字稿/转写网关地址。 |
| `TRANSCRIPTION_VOC_TOKEN` | 转写网关 token。 |
| `VOICE_TOKEN` / `OPENCLAW_VOC_TOKEN` | 语音及转写链路使用的兼容 token。 |
### LLM
| 变量 | 用途 |
|---|---|
| `LLM_BASE_URL` | OpenAI 兼容的 LLM 代理地址。 |
| `LLM_API_KEY` | AI 助手、脚本生成和媒体理解使用的密钥。 |
### 七牛云
| 变量 | 用途 |
|---|---|
| `QINIU_AK` / `QINIU_SK` | 七牛 Access Key 和 Secret Key。 |
| `QINIU_BUCKET` | 存储空间名称。 |
| `QINIU_DOMAIN` / `QINIU_CDN_DOMAIN` | 文件访问域名。 |
| `QINIU_CDN_PREFIX` | 上传文件的路径前缀。 |
| `QINIU_UPLOAD_URL` | 七牛上传地址。 |
### 语音合成
| 变量 | 用途 |
|---|---|
| `VOLC_TTS_TOKEN` | 火山 TTS token。 |
| `VOLC_SPEECH_API_KEY` | 火山语音 API Key 鉴权。 |
| `VOLC_SPEECH_APP_KEY` / `VOLC_SPEECH_ACCESS_KEY` | 火山语音 App Key 鉴权。 |
| `VOICE_TTS_BASE_URL` | 云函数语音代理地址。 |
### Quickly
| 变量 | 用途 |
|---|---|
| `QUICKLY_APP_KEY` / `QUICKLY_APP_SECRET` | Quickly 应用凭证。 |
| `QUICKLY_ACCOUNT_ID` | Quickly 账号 ID。 |
| `QUICKLY_CALLBACK_URL` | 任务回调地址。 |
| `QUICKLY_RELAY_URL` | 云函数中继地址。 |
| `QUICKLY_UPSTREAM_FN_ID` | 上游一键成片函数 ID。 |
多数变量只在调用对应真实服务时需要。只查看界面或开发不依赖外部服务的功能时,可以先保留为空。
云函数 ID 维护在:
```text
src/app/services/cloud-functions.ts
```
## 本地运行
### 同时启动前后端
```bash
npm run dev
```
- Angular:
- Express:
### 仅启动前端
```bash
npm start
```
该命令会使用 `proxy.conf.json`。主要代理关系:
| 前端路径 | 目标 |
|---|---|
| `/api` | `https://api.tikhub.io` |
| `/jimeng` | `https://server.fmode.cn/api/volcengine/jimeng` |
| `/parse` | `https://server.fmode.cn/parse` |
| `/functions` | `https://server.fmode.cn/api/functions` |
| `/backend` | `http://localhost:3000` |
### 允许局域网访问前端
```bash
npm run start:dev
```
该命令监听 `0.0.0.0`。请确认所在网络可信,并避免在前端或 URL 中暴露凭证。
### 仅启动本地后端
```bash
npm run server
```
修改 `PORT` 后,需同步调整 `proxy.conf.json` 中 `/backend` 的目标地址。
### 开发模式持续构建
```bash
npm run watch
```
## 测试
### 启用提交前文档提醒
仓库提供 `.githooks/pre-commit`:当核心服务、Express 路由或云函数发生改动但没有同步协作文档时,会打印警告,但不会阻断提交。每个新工作副本首次使用时执行:
```bash
git config core.hooksPath .githooks
```
### Angular 单元测试
```bash
npm test
```
执行一次后退出:
```bash
npm test -- --watch=false
```
### IP 操盘 Playwright E2E
```bash
npm run e2e:ip-operator
```
脚本会在 `127.0.0.1:4300` 启动 Angular 开发服务器,并使用 Playwright 的 Edge 通道运行测试。
运行真实 LLM 用例:
```bash
npm run e2e:ip-operator:real
```
真实用例需要对应服务可访问并已配置凭证,可能产生外部调用。
### 云函数与治理校验
```bash
npm run build:cloud-functions
npm run validate:cloud-functions
npm run validate:jimeng-billing
npm run validate:storage-policy
npm run smoke:cloud
npm run review:guard
```
- `build:cloud-functions`:生成可直接部署的单文件云函数到 `cloud-functions/deployable/`。
- `smoke:cloud`:检查已配置云函数的连通性;空函数 ID 会被跳过。
- `review:guard`:检查疑似凭证和部分代码体积治理规则。
需要登录态的云函数或账号隔离验收还会使用 `SMOKE_SESSION_TOKEN`、`STORAGE_GOVERNANCE_SESSION_A` 等测试环境变量。它们只能临时设置在本地终端中,不能写入源码或文档。
## 构建与部署
### 生产构建
```bash
npm run build
```
Angular 项目名为 `Tik-tok`,默认构建输出位于:
```text
dist/Tik-tok/
```
### 前端内部部署
仓库使用根目录的 `deploy.ps1` 发布前端:
```powershell
.\deploy.ps1
```
脚本会:
1. 使用 `/dev/video-workflow/` 作为 `base-href` 构建前端。
2. 将 `dist/video-workflow/browser` 同步到华为云 OBS。
3. 设置公开读取权限。
4. 刷新对应 CDN 目录。
部署地址由脚本配置为:
```text
https://app.fmode.cn/dev/video-workflow/
```
执行前需检查 `deploy.ps1` 中的 `obsutil`、`hcloud` 本机路径及部署配置。该脚本被 `.gitignore` 忽略,属于内部本地部署配置,不应提交或对外分享其中的凭证。
### 云函数部署
云函数源码位于 `cloud-functions/`。依赖 `_session.js` 的函数不能直接复制源码部署,应先运行:
```bash
npm run build:cloud-functions
```
然后将 `cloud-functions/deployable/` 下的对应单文件版本部署到 fmode 平台,并把函数 ID 更新到:
```text
src/app/services/cloud-functions.ts
```
部署后执行:
```bash
npm run smoke:cloud
npm run build
```
## 项目结构简述
```text
video-workflow/
├── src/
│ ├── main.ts # Angular 启动入口
│ ├── environments/ # 开发/生产环境编译配置
│ └── app/
│ ├── app.ts # 应用主壳与全局工作台逻辑
│ ├── components/ # 通用 UI 组件
│ ├── models/ # 业务模型
│ ├── pages/ # 页面与各生成 Pipeline
│ ├── pipelines/ # Pipeline 注册中心
│ ├── pipes/ # 展示格式化管道
│ └── services/ # API、存储和业务服务
├── server.js # Express 启动入口
├── server/
│ ├── config/ # 后端运行时配置
│ └── routes/ # Express 路由模块
├── cloud-functions/ # fmode 云函数源码与部署说明
├── scripts/ # 构建、冒烟和治理脚本
├── e2e/ # Playwright 端到端测试
├── public/ # 静态资源
├── data/ # 本地运行数据,不进入版本库
├── proxy.conf.json # Angular 开发代理
├── angular.json # Angular 构建配置
├── playwright.config.ts # E2E 配置
├── .env.example # 本地配置模板
└── deploy.ps1 # 内部前端部署脚本,本地保留
```
生成模式由 `src/app/pipelines/pipeline-registry.ts` 统一登记,但新增模式还需要同步接入页面组件、Tab 类型和主模板。
## 常见问题
### 页面能打开,但调用 `/backend` 失败
确认 Express 已启动:
```bash
npm run server
```
然后访问:
```text
http://localhost:3000/api/health
```
如果修改了 `PORT`,还需更新 `proxy.conf.json`。
### 提示未检测到 FFmpeg 或 ffprobe
安装 FFmpeg,并确保下面两个命令可在当前终端执行:
```bash
ffmpeg -version
ffprobe -version
```
重启终端和本地后端后再试。
### Whisper 转写不可用
确认 CLI 已安装:
```bash
whisper --help
```
也可以访问:
```text
http://localhost:3000/api/whisper/status
```
### 生成、LLM、抖音或上传功能提示未配置
1. 检查 `.env` 中对应能力的 URL 和 token。
2. 检查 `src/app/services/cloud-functions.ts` 中对应函数 ID。
3. 重新启动 `npm run server`,使后端重新加载 `.env`。
4. 对云函数执行 `npm run smoke:cloud`。
### 登录后数据为空或不同账号数据不同
这是账号隔离行为。项目使用当前 Parse 用户的 `objectId` 区分云端业务数据和浏览器本地数据。
### Playwright 找不到浏览器
当前配置使用 Microsoft Edge。先确认本机已安装 Edge;必要时安装 Playwright 浏览器依赖:
```bash
npx playwright install msedge
```
### `deploy.ps1` 提示找不到工具
检查脚本顶部配置的 `obsutil` 和 `hcloud` 路径是否与本机一致,并确认部署账号具备 OBS 同步、ACL 修改和 CDN 刷新权限。
## 内部使用说明
本仓库为公司私有项目。源码、业务文档、云函数 ID、服务地址、用户数据和访问凭证不得对外分发。