Skip to content

About

用自然语言驱动 AI,一句话完成音视频处理 — 微信小程序

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

97 Commits

Folders and files

Repository files navigation

言影智剪

用自然语言驱动 AI,一句话完成音视频处理 — 微信小程序
FastAPI · FFmpeg · arq + Redis · 平台内置 LLM · 多步管线编排 · 执行前预检澄清

Quick Start MIT License Version v1.3.3

WeChat MiniProgram Python 3.13 FastAPI arq + Redis SQLite + SQLAlchemy FFmpeg Docker Compose


项目简介

言影智剪是一个基于 AI(Agnes 2.5 Flash / DeepSeek)+ FFmpeg 的微信小程序。用户上传音视频文件后用自然语言描述处理需求(如"转为 MP3"、"裁剪前 30 秒"、"加个水印"、"压缩到 10MB"、"倒放"、"两个视频拼接后 2 倍速"),AI 自动理解意图、拆解为多步处理管线,后端拼装 FFmpeg 命令依次执行,完成后即可下载结果。

核心链路:上传文件 → 描述任务 → 执行前预检(参数缺失时自动追问澄清)→ AI 拆解多步 plan(8 个通用 tool → 23 个底层操作)→ 用户确认步骤 → arq 异步队列串行执行 FFmpeg → 下载结果

AI 模型由平台内置提供(Agnes 2.5 Flash 免费、DeepSeek 按积分计费),用户无需自备 API Key;每日签到可领取积分。积分不足时自动降级免费模型并提示,签到回血后自动恢复为用户所选模型。

核心特性

  • 自然语言即操作 — 一句话描述需求,AI 拆解为单步或多步 FFmpeg 管线,无需学习任何命令
  • 执行前预检 + 澄清(所见即所得) — 提交前展示中文步骤预览,参数缺失时追问(最多 5 轮、同一参数最多追问 3 次),确认后的步骤即执行依据;无法澄清时明确提示改写描述,不按默认参数静默执行
  • 平台内置模型,零 Key 门槛 — Agnes 2.5 Flash 免费、DeepSeek 按积分计费,余额不足自动降级并在"我的"页如实显示当前生效模型
  • 参数契约单一数据源 — 23 个操作的参数(类型 / 枚举 / 默认值 / 中文别名 / 输入数量与类型)全部声明在 operations.yaml,规划期归一化校验、启动期 fail-fast,非法值显式失败
  • 多步管线编排 — 支持"先多文件合成、再对结果做后处理",执行器独立于任务入口;replan 失败限 1 次,全局超时预算(默认 1800s)防止长任务失控
  • 文件生命周期自动化 — 原始文件处理完即删、中间产物清理,结果文件 30 分钟后自动清理(cleanup.sh 兜底 60 分钟),成功结果可"继续处理"免重传

支持的操作

底层共 23 个操作(定义于 backend/app/config/operations.yaml),对 AI 暴露为 8 个通用 tool(映射关系见 backend/app/services/tool_mapping.py)。

分类 能力
格式与编码 格式转换(MP4 / MKV / MOV / AVI / MP3 / WAV / AAC / FLAC / OGG / M4A / WMA)、提取音频、去除原生音轨
剪辑与时长 裁剪(前 N 秒 / 中间片段 / 保留末尾)、变速(0.25~4.0 倍速)、倒放(视频画面与声音同倒,长视频自动分段不受时长限制)
画面 分辨率调整(480p / 720p / 1080p / 4K)、画面裁剪(居中裁至指定宽高比,如 1:1 / 16:9 / 4:3)、旋转与镜像翻转、压缩(按质量或目标体积)、画质增强、画面降噪
音频 音量调节(0~5.0 倍)、变调(音高变换,不改变时长)、音频降噪、混音、音频拼接、替换音轨、添加音轨 / 配音
水印与字幕 文字水印(自定义内容 / 位置 / 字号,支持中文)、图片水印(PNG / JPG / WebP,可调缩放)、字幕烧录(SRT / ASS)
多文件 视频合并、音频拼接与混音、多文件组合操作(一次最多 9 个文件)

支持的输入格式:视频 mp4/avi/mov/mkv/flv/wmv/webm、音频 mp3/wav/aac/flac/ogg/wma/m4a、图片 png/jpg/jpeg/webp、字幕 srt/ass。

快速开始

1. 克隆仓库并生成配置文件

git clone <your-repo-url> && cd media-workshop

cp backend/.env.example backend/.env
cp miniprogram/utils/constants.example.js miniprogram/utils/constants.js
cp miniprogram/project.config.example.json miniprogram/project.config.json

backend/.env、miniprogram/utils/constants.js、miniprogram/project.config.json 均被 .gitignore 忽略。共享常量(版本更新记录、首页标签、轮询与澄清上限等)必须先改 constants.example.js,否则改动不会进仓库。

2. 填写配置

编辑 backend/.env,至少填好微信凭证与平台模型 Key:

WECHAT_APPID=wx你的AppID
WECHAT_SECRET=你的AppSecret
JWT_SECRET=生成一个随机字符串(至少32位)

# 平台内置 AI 模型(providers.yaml 经 ${VAR} 引用;enabled 的模型缺 Key 会拒绝启动)
AGNES_API_KEY=             # 免费模型,不消耗积分
AGNES_BASE_URL=https://api.agnes-ai.cn/v1
DEEPSEEK_API_KEY=          # 付费模型,按积分计费
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1

再编辑 miniprogram/project.config.json 填写小程序 AppID;miniprogram/utils/constants.js 的 BASE_URL 指向后端地址。

3. 启动后端(推荐 Docker Compose)

docker compose up -d

4. 在微信开发者工具中导入 miniprogram/,填写 AppID,开发阶段勾选"不校验合法域名"。

使用示例

小程序内

首页提供示例标签(来源 miniprogram/utils/constants.example.js):转成MP3、合并视频、视频增强、音频降噪、裁剪前30秒、压缩视频、换背景音乐、加配音、去掉原声、烧录字幕 等。

典型描述如:把这两个视频拼起来再 2 倍速、去掉背景音乐换成我上传的音频、压缩到 10MB 以内。

HTTP 调用链

# 1. 微信登录换取 JWT(code 来自 wx.login)
curl -X POST http://localhost:8000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"code":"<wx.login 返回的 code>"}'

# 2. 上传文件,拿到 file_id
curl -X POST http://localhost:8000/api/upload \
  -H "Authorization: Bearer <token>" \
  -F "file=@demo.mp4"

# 3. 执行前预检:type=plan 返回可确认步骤,type=clarify 返回待补充问题
curl -X POST http://localhost:8000/api/tasks/preview \
  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d '{"description":"转成MP3并压缩到10MB以内","file_ids":["<file_id>"]}'

# 4. 确认步骤快照后提交任务:STEPS_JSON 为上一步 preview 返回的 steps 原样回传,即以所见步骤执行
curl -X POST http://localhost:8000/api/tasks \
  -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
  -d "{\"description\":\"转成MP3并压缩到10MB以内\",\"file_ids\":[\"<file_id>\"],\"preview_plan\":${STEPS_JSON}}"

# 5. 轮询进度(current_step / total_steps),完成后下载结果
curl http://localhost:8000/api/tasks/<task_id> -H "Authorization: Bearer <token>"
curl -o result.mp3 http://localhost:8000/api/download/<task_id> -H "Authorization: Bearer <token>"

系统架构

flowchart TD
    MP["微信小程序(原生框架)<br/>首页 / 历史 / 我的 / 帮助 / 协议"]
    NG["Nginx 反向代理<br/>仅放行 /api/ 与 /static/"]
    API["FastAPI 后端<br/>auth / upload / task / download / user / agreement / credit"]
    DB[("SQLite<br/>SQLAlchemy ORM")]
    RQ[("Redis<br/>arq 队列")]
    WK["arq Worker<br/>process_media_task"]
    PIPE["planner + executor<br/>预检澄清 · 多步 plan 编排"]
    LLM["平台内置模型<br/>Agnes 2.5 Flash(免费)<br/>DeepSeek(积分计费)"]
    OPS["operations.yaml<br/>参数契约 + FFmpeg 模板"]
    FF["FFmpeg<br/>音视频处理引擎"]
    OUT["结果文件<br/>30 分钟后自动清理"]

    MP -->|"HTTPS + JWT"| NG
    NG --> API
    API --> DB
    API -->|"提交任务入队"| RQ
    RQ --> WK
    WK --> PIPE
    PIPE -->|"OpenAI 兼容 Function Calling"| LLM
    PIPE --> OPS
    PIPE --> FF
    FF --> OUT
    API -->|"预检 preview"| LLM
    OUT -->|"下载 / 继续处理"| NG

    classDef fe fill:#07C160,stroke:#057A3B,color:#ffffff
    classDef gw fill:#269539,stroke:#1B6B28,color:#ffffff
    classDef api fill:#009688,stroke:#00695C,color:#ffffff
    classDef store fill:#003B57,stroke:#00212F,color:#ffffff
    classDef queue fill:#DC382D,stroke:#9C231A,color:#ffffff
    classDef worker fill:#FB8C00,stroke:#B35F00,color:#ffffff
    classDef llm fill:#6C5CE7,stroke:#4834C4,color:#ffffff
    classDef media fill:#1565C0,stroke:#0D3F7A,color:#ffffff
    classDef result fill:#546E7A,stroke:#32424A,color:#ffffff

    class MP fe
    class NG gw
    class API api
    class DB store
    class RQ queue
    class WK,PIPE worker
    class LLM llm
    class OPS,FF media
    class OUT result
Loading

处理链路:上传落盘 → /api/tasks/preview 预检(LLM 判断 plan / clarify / terminated)→ 用户确认步骤 → /api/tasks 落库入队 → arq worker 取出确认快照(校验失败则回退 AI 拆解)→ executor 逐步拼装并执行 FFmpeg → 终局清理输入与中间产物 → 结果延迟清理入队。

配置说明

环境变量(backend/.env,完整清单见 backend/.env.example 与 backend/app/config.py)

变量 默认值 说明
WECHAT_APPID / WECHAT_SECRET — 小程序凭证,用于 code2session 登录
JWT_SECRET dev-secret-change-me JWT 签名密钥(HS256),生产必须替换
JWT_EXPIRE_HOURS 720 Token 有效期(小时)
AGNES_API_KEY / AGNES_BASE_URL — / https://api.agnes-ai.cn/v1 免费模型 Agnes 2.5 Flash
DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL — / https://api.deepseek.com/v1 付费模型 deepseek-chat
UPLOAD_DIR / RESULT_DIR /data/uploads / /data/results 上传与结果目录
MAX_VIDEO_SIZE_MB 200 上传上限(音频 50 / 图片 10 / 字幕 2)
FFMPEG_TIMEOUT_SECONDS 300 单条 ffmpeg 命令超时(秒)
FFMPEG_CONCURRENCY 1 ffmpeg 并发数
TASK_TOTAL_TIMEOUT_SECONDS 1800 多步 plan 整体超时预算(秒),超时整单失败
TASK_POLL_MAX_SECONDS 300 前端最长轮询等待(秒)
REVERSE_SEGMENT_SECONDS 45 倒放自动分段的单段时长阈值(秒)
REDIS_URL / DATABASE_URL redis://localhost:6379 / sqlite:///./media_workshop.db 队列与数据库连接
ENABLE_DOCS true 是否开放 /docs、/redoc(生产建议 false)
LOG_LEVEL INFO app.* 日志级别(root 固定 INFO 抑制第三方噪音)
CHECKIN_DAILY_CREDITS 10 每日签到发放积分
CREDIT_TOKEN_BASE 1000 每 1000 token 折算 1 积分(向下取整)
CREDIT_DOWNGRADE_THRESHOLD 0 余额 ≤ 阈值时付费模型降级为免费模型
DEFAULT_PROVIDER_ID agnes 新用户默认模型(须与 providers.yaml 中 is_default 一致)
MAX_CLARIFY_ROUNDS 5 预检澄清最大轮数,超限终止提交
MAX_SAME_PARAM_ASKS 3 同一必填参数重复追问上限,达到即判无效澄清

配置文件

文件 作用
backend/app/config/providers.yaml 平台内置模型清单:model_name、credit_multiplier、is_free、is_default、enabled;api_key / base_url 用 ${VAR} 引用环境变量,启用项缺 Key 时启动即拒绝
backend/app/config/operations.yaml 全部 FFmpeg "数据":格式→编码器组合、压缩 CRF 映射、水印与增强参数、滤镜模板,以及每个操作的输入约束、输出扩展名规则与参数契约
miniprogram/utils/constants.example.js 前端常量:BASE_URL、文件大小与轮询限制、澄清轮次上限、首页示例标签、版本更新记录

API 接口

除 /api/health、登录与协议接口外,均需 Authorization: Bearer <token>。

方法 路径 说明
GET /api/health 健康检查(Docker healthcheck 使用)
POST /api/auth/login 微信登录,返回 JWT 与协议同意状态
POST /api/upload 上传文件(视频/音频/图片/字幕),返回 file_id 与 kind
DELETE /api/upload/{file_id} 删除已上传但未被任务引用的文件(多文件上传失败时清理孤儿文件)
POST /api/tasks/preview 执行前预检:返回 plan(可执行步骤)/ clarify(澄清问题)/ terminated(无法澄清);携带 clarify_round、last_answers 供轮次裁决
POST /api/tasks 提交处理任务(支持 file_ids 数组与 preview_plan 确认快照),返回实际生效模型与是否降级
GET /api/tasks 历史任务列表(分页)
GET /api/tasks/{task_id} 查询任务状态(含 current_step / total_steps 步骤进度)
POST /api/tasks/{task_id}/reuse/prepare 继续处理前置:把旧任务结果预置为可引用的上传文件并返回 file_id
POST /api/tasks/{task_id}/reuse 继续处理:以 base_file_id 为输入创建新任务,支持追加文件与 preview_plan 快照
DELETE /api/tasks/{task_id} 删除任务
GET /api/download/{task_id} 下载结果文件
GET /api/providers 可用 AI 模型列表(含用户所选 selected 与实际生效 effective)
POST /api/user/provider 切换用户所选模型
POST /api/checkin 每日签到领取积分
GET /api/credits 查询积分余额与签到状态(含降级标记与当前生效模型)
GET /api/credits/transactions 积分流水明细
GET /api/user/profile 获取用户资料
PUT /api/user/profile 更新用户资料(昵称)
POST /api/user/avatar 上传头像
GET /api/agreements/user 获取用户协议
GET /api/agreements/privacy 获取隐私协议
POST /api/agreements/agree 提交协议同意记录

ENABLE_DOCS=true 时可访问 /docs(Swagger UI,静态资源走 bootcdn 以便国内直连)与 /redoc。

项目结构

media-workshop/
├── miniprogram/                      # 微信小程序前端(原生框架)
│   ├── pages/                        # 页面:index 首页 / history 历史 / mine 我的 / help 帮助 / agreement 协议
│   ├── utils/                        # constants.example.js(全局常量模板)、download.js、format.js
│   ├── images/                       # 图标与 TabBar 资源
│   ├── app.js / app.json / app.wxss  # 应用入口、页面与 TabBar 配置、全局样式
│   └── project.config.example.json   # 开发者工具项目配置模板
├── backend/                          # Python 后端
│   ├── app/
│   │   ├── config/                   # operations.yaml(FFmpeg 参数契约)、providers.yaml(内置模型)
│   │   ├── models/                   # 数据模型(用户 / 任务 / 任务文件 / 协议)
│   │   ├── schemas/                  # 请求/响应 Pydantic Schema
│   │   ├── routers/                  # API 路由:auth / upload / task / download / user / agreement / credit
│   │   ├── services/                 # 业务逻辑:planner 拆解、executor 执行、ffmpeg、LLM、积分、provider 解析等
│   │   ├── tasks/                    # arq Worker(process_media_task / cleanup_result_file)
│   │   ├── middleware/               # JWT 鉴权与协议校验依赖
│   │   ├── config.py                 # 环境变量集中定义
│   │   ├── database.py / main.py     # 会话初始化、FastAPI 应用装配
│   │   └── seed_data.py              # 协议版本种子数据
│   ├── tests/                        # 17 个 pytest 用例文件(预检、执行器、FFmpeg、积分、provider 等)
│   ├── deploy/                       # cleanup.sh 兜底清理、generate_icons.py 图标生成
│   ├── Dockerfile                    # python:3.13-slim + ffmpeg + 中文字体
│   └── requirements.txt              # 依赖锁定版本
├── deploy/
│   └── nginx-docker.conf             # Nginx 反向代理(仅放行 /api/ 与 /static/,其余 403)
├── docs/                             # 需求 / 开发 / 部署 / 规范文档(见下)
├── docker-compose.yml                # 一键部署:nginx + fastapi + worker + redis
└── LICENSE

docs/ 目录包含:需求文档与开发文档(v1.0 ~ v1.3.3 全版本)、服务启动与部署文档.md(Windows 本地 / CentOS 生产 / Docker 三套环境)、代码注释规范.md、协议与应用版本更新指南.md、未来能力设想.md。

技术栈

层级 技术
前端 微信小程序原生框架(基础库 ≥ 2.25.0)
后端框架 FastAPI 0.115 + Uvicorn
异步队列 arq 0.26 + Redis(redis-py 5.2)
数据库 SQLite(SQLAlchemy 2.0 ORM)
AI 服务 平台内置模型(Agnes 2.5 Flash 免费 / DeepSeek 付费),OpenAI 兼容 Function Calling
音视频处理 FFmpeg(容器内安装 ffmpeg + fonts-noto-cjk / fonts-dejavu-core 供中文水印)
图片处理 Pillow(文字水印渲染)
认证 JWT(HS256,PyJWT)
部署 Docker Compose(Nginx + FastAPI + arq Worker + Redis)
测试 pytest 8 + pytest-asyncio

部署

Docker Compose(推荐)

cp backend/.env.example backend/.env   # 填好配置
docker compose up -d
服务 容器名 端口 说明
fastapi media-fastapi 8000 后端 API(健康检查打 /api/health)
nginx media-nginx 80 / 443 反向代理,配置挂载自 deploy/nginx-docker.conf
redis media-redis 6379 arq 消息队列(healthcheck 用 redis-cli ping)
worker media-worker — arq 异步任务,ENABLE_DOCS=false
  • 数据卷:uploads_data / results_data / sqlite_data,数据库落在 /app/db,重启不丢数据。
  • SSL:证书放入 deploy/ssl/(挂载到 /etc/nginx/ssl),nginx-docker.conf 中替换 your-domain.com 与证书文件名。
  • 上传体积:Nginx client_max_body_size 210m,并关闭 proxy_request_buffering 以直传大文件。
  • 真实 IP:FORWARDED_ALLOW_IPS=172.16.0.0/12 信任 Docker 内网代理,访问日志记录真实客户端 IP(自动过滤健康检查与 404 探测噪音)。

本地开发

cd backend
pip install -r requirements.txt

redis-server                                         # 启动 Redis
uvicorn app.main:app --reload                        # 启动 FastAPI
arq app.tasks.process_task.WorkerSettings            # 另开终端启动 Worker

Windows 本地开发还需自行安装 FFmpeg 并加入 PATH;中文字体路径可通过 WATERMARK_FONT_PATH / WATERMARK_FONT_PATH_CJK 覆盖(详见 backend/.env.example 与 docs/服务启动与部署文档.md)。

运行测试

cd backend
pytest tests/ -v

兜底清理

backend/deploy/cleanup.sh 兜底删除超过 60 分钟的上传与结果文件(正常流程由 arq 延迟任务负责:输入立即删除、结果 30 分钟后删除)。

贡献指南

  1. Fork 本仓库并创建特性分支:git checkout -b feat/your-feature
  2. 提交前请确保本地测试通过:cd backend && pytest tests/ -v
  3. 新增或修改 FFmpeg 操作时,请同步更新 backend/app/config/operations.yaml(参数契约单一数据源)并补充 backend/tests/ 用例
  4. 涉及前端共享常量的改动,请修改 miniprogram/utils/constants.example.js 而非被忽略的 constants.js
  5. 提交信息建议使用 feat: / fix: / docs: / refactor: / test: 前缀
  6. 发起 Pull Request 并说明变更动机与验证方式

License

MIT © 2026 言影智剪

About

用自然语言驱动 AI,一句话完成音视频处理 — 微信小程序

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages