readme
This commit is contained in:
217
readme.md
Normal file
217
readme.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
好的,这是基于你提供的代码生成的详细 `README.md` 文档。
|
||||||
|
|
||||||
|
# 数字人生成服务
|
||||||
|
|
||||||
|
本项目提供一个后端服务,用于根据文本和样本媒体(视频、音频)生成数字人。它利用后台线程处理视频和音频处理等资源密集型操作,以实现异步任务处理。
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
## 系统架构
|
||||||
|
|
||||||
|
该服务基于 **Flask** Web 框架,并遵循 **RESTful API** 设计。主要组件包括:
|
||||||
|
|
||||||
|
- **API 端点**: 用于文件上传、数字人生成、音频提取和任务状态查询的路由。
|
||||||
|
- **异步任务处理**: 像视频处理 (`api_extract_audio`) 和数字人生成 (`api_generate_digital_human`) 这样的繁重任务使用 **Python 的 `threading` 模块**在后台非阻塞地处理。这可以防止主 Flask 应用被阻塞,确保 API 保持响应。
|
||||||
|
- **任务管理**: 一个全局字典 (`TASKS`) 用于存储每个异步任务的状态、进度和结果,并通过一个唯一的 `task_id` 进行访问。
|
||||||
|
- **文件管理**: 服务使用 `FileManager` 类处理文件上传和存储,将文件组织到 `video` 和 `audio` 子目录中。
|
||||||
|
- **错误处理**: 自定义的 `APIException`、`404 Not Found` 和 `500 Internal Server Error` 错误处理器提供了统一且信息丰富的响应。
|
||||||
|
|
||||||
|
整体流程如下:
|
||||||
|
|
||||||
|
1. 客户端向生成端点(例如,`/api/digital_human/generate`)发送请求。
|
||||||
|
2. 服务器验证请求并创建一个带有唯一 `task_id` 的新任务。
|
||||||
|
3. 服务器生成一个新的后台线程来执行生成逻辑。
|
||||||
|
4. 服务器立即返回一个 `submitted` 状态和 `task_id` 给客户端。
|
||||||
|
5. 客户端随后可以轮询 `/api/task/status/<task_id>` 端点,以检查进度并在任务完成时获取最终结果。
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
## 运行环境
|
||||||
|
|
||||||
|
要运行此服务,你需要设置一个包含所需库的 Python 环境。
|
||||||
|
|
||||||
|
### 运行要求
|
||||||
|
|
||||||
|
- **Python 3.6+**: 代码使用了 f-string 和类型提示,这些都是现代 Python 的标准特性。
|
||||||
|
- **`moviepy`**: 用于视频和音频处理,特别是从视频文件中提取音频。
|
||||||
|
- **`Flask`**: 核心 Web 框架。
|
||||||
|
- **`Flask-CORS`**: 处理跨域资源共享,允许来自不同域的请求。
|
||||||
|
|
||||||
|
### 安装
|
||||||
|
|
||||||
|
1. 克隆此仓库(或将提供的代码保存为 `app.py`)。
|
||||||
|
2. 使用 `pip` 安装所需的 Python 包:
|
||||||
|
```bash
|
||||||
|
pip install Flask Flask-Cors moviepy
|
||||||
|
```
|
||||||
|
3. 确保你的系统已安装 `moviepy` 的必要依赖项,例如 **FFmpeg**。`moviepy` 通常会自动处理,但在某些系统上你可能需要手动安装。
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
## 部署方法
|
||||||
|
|
||||||
|
### 本地开发
|
||||||
|
|
||||||
|
1. 确保你已安装所有先决条件。
|
||||||
|
2. 直接从命令行运行应用程序:
|
||||||
|
```bash
|
||||||
|
python app.py
|
||||||
|
```
|
||||||
|
3. 服务将在 `http://0.0.0.0:5001` 上可用。
|
||||||
|
|
||||||
|
### Docker 部署(推荐)
|
||||||
|
|
||||||
|
为了确保一个一致且隔离的环境,强烈推荐使用 Docker 进行部署。
|
||||||
|
|
||||||
|
1. **创建 `Dockerfile`**:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# 使用官方 Python 运行时作为父镜像
|
||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
# 设置容器中的工作目录
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 将当前目录内容复制到容器的 /app 目录中
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 安装 requirements.txt 中指定的所需包
|
||||||
|
RUN pip install --no-cache-dir Flask Flask-Cors moviepy
|
||||||
|
|
||||||
|
# 暴露应用程序运行的端口
|
||||||
|
EXPOSE 5001
|
||||||
|
|
||||||
|
# 定义环境变量
|
||||||
|
ENV FLASK_APP=app.py
|
||||||
|
|
||||||
|
# 运行应用程序
|
||||||
|
CMD ["flask", "run", "--host=0.0.0.0", "--port=5001"]
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **创建 `requirements.txt` 文件**:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Flask
|
||||||
|
Flask-Cors
|
||||||
|
moviepy
|
||||||
|
```
|
||||||
|
|
||||||
|
这有助于 Docker 更有效地构建镜像。
|
||||||
|
|
||||||
|
3. **构建并运行 Docker 容器**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t digital-human-service .
|
||||||
|
docker run -p 5001:5001 digital-human-service
|
||||||
|
```
|
||||||
|
|
||||||
|
`-p 5001:5001` 标志将主机上的 5001 端口映射到容器中的 5001 端口。
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
## API 文档
|
||||||
|
|
||||||
|
所有 API 端点都以 `/api` 为前缀。
|
||||||
|
|
||||||
|
### 1\. 生成数字人
|
||||||
|
|
||||||
|
- **端点**: `POST /api/digital_human/generate`
|
||||||
|
- **描述**: 启动一个后台任务,根据提供的文本、视频和音频生成数字人视频。
|
||||||
|
- **请求体**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"speech_text": "Hello, this is a test.",
|
||||||
|
"sample_video": "my-video-file.mp4",
|
||||||
|
"sample_voice": "my-voice-file.wav"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **成功响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "submitted",
|
||||||
|
"task_id": "a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890",
|
||||||
|
"query_url": "/api/task/status/a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2\. 从视频中提取音频
|
||||||
|
|
||||||
|
- **端点**: `POST /api/video/extract_audio`
|
||||||
|
- **描述**: 启动一个后台任务,从视频文件中提取音轨。
|
||||||
|
- **请求体**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"video_path": "/path/to/my-video.mp4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **成功响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "submitted",
|
||||||
|
"task_id": "f6e5d4c3-b2a1-0987-6543-210fedcba987",
|
||||||
|
"query_url": "/api/task/status/f6e5d4c3-b2a1-0987-6543-210fedcba987"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3\. 查询任务状态
|
||||||
|
|
||||||
|
- **端点**: `GET /api/task/status/<task_id>`
|
||||||
|
- **描述**: 获取正在运行任务的当前状态。
|
||||||
|
- **成功响应(待处理/运行中)**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "running",
|
||||||
|
"progress": 50,
|
||||||
|
"type": "digital_human",
|
||||||
|
"params": { ... },
|
||||||
|
"result": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **成功响应(已完成)**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "completed",
|
||||||
|
"progress": 100,
|
||||||
|
"type": "digital_human",
|
||||||
|
"params": { ... },
|
||||||
|
"result": {
|
||||||
|
"uuid": "my-video-uuid",
|
||||||
|
"download_url": "/download/generated/video/my-video-uuid?task_id=200"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4\. 文件上传
|
||||||
|
|
||||||
|
- **端点**: `POST /api/upload/video`
|
||||||
|
- **描述**: 上传视频文件。
|
||||||
|
- **表单数据**: `file`(视频文件)、`custom_name`(可选)。
|
||||||
|
- **端点**: `POST /api/upload/audio`
|
||||||
|
- **描述**: 上传音频文件。
|
||||||
|
- **表单数据**: `file`(音频文件)、`custom_name`(可选)。
|
||||||
|
- **成功响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "视频上传成功",
|
||||||
|
"file_info": { ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5\. 下载生成的视频
|
||||||
|
|
||||||
|
- **端点**: `GET /download/generated/video/<uuid>`
|
||||||
|
- **描述**: 提供之前生成的视频文件下载。
|
||||||
|
- **参数**:
|
||||||
|
- `uuid`: 视频文件的唯一 ID。
|
||||||
|
- `task_id`(可选): 生成该视频的任务 ID。
|
||||||
|
|
||||||
|
### 6\. 文件列表与查找
|
||||||
|
|
||||||
|
- **端点**: `GET /api/files/list`
|
||||||
|
- **描述**: 列出指定目录中可用的文件。
|
||||||
|
- **查询参数**:
|
||||||
|
- `directory`: 目录路径。
|
||||||
|
- `file_type`: `video`、`audio` 或 `all`(默认)。
|
||||||
|
- **端点**: `GET /api/files/find/<uuid>`
|
||||||
|
- **描述**: 按 UUID 查找生成的文件。
|
||||||
Reference in New Issue
Block a user