From 3f37cb80b85096537d06470af5a6a33f13d4c776 Mon Sep 17 00:00:00 2001 From: wall-E <18810335268@163.com> Date: Fri, 5 Sep 2025 00:49:07 +0800 Subject: [PATCH] readme --- readme.md | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 readme.md diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..fba7ce5 --- /dev/null +++ b/readme.md @@ -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/` 端点,以检查进度并在任务完成时获取最终结果。 + +----- + +## 运行环境 + +要运行此服务,你需要设置一个包含所需库的 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/` + - **描述**: 获取正在运行任务的当前状态。 + - **成功响应(待处理/运行中)**: + ```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`: 视频文件的唯一 ID。 + - `task_id`(可选): 生成该视频的任务 ID。 + +### 6\. 文件列表与查找 + + - **端点**: `GET /api/files/list` + - **描述**: 列出指定目录中可用的文件。 + - **查询参数**: + - `directory`: 目录路径。 + - `file_type`: `video`、`audio` 或 `all`(默认)。 + - **端点**: `GET /api/files/find/` + - **描述**: 按 UUID 查找生成的文件。 \ No newline at end of file