218 lines
9.4 KiB
Markdown
218 lines
9.4 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Commands
|
||
|
||
```bash
|
||
# 下载依赖
|
||
go mod download
|
||
|
||
# 编译
|
||
go build -o media main.go
|
||
|
||
# 运行(开发)
|
||
go run main.go
|
||
|
||
# 格式化代码
|
||
go fmt ./...
|
||
|
||
# 代码检查
|
||
go vet ./...
|
||
|
||
# Docker 构建(多阶段构建,包含 FFmpeg 和 whisper 运行时)
|
||
docker build -t media .
|
||
|
||
# Docker 运行
|
||
docker run -p 3010:3010 media
|
||
```
|
||
|
||
## Architecture
|
||
|
||
这是一个多媒体处理微服务项目,基于 GoFrame 框架开发,提供视频处理、音频提取、语音识别、字幕叠加等功能。
|
||
|
||
### 目录结构
|
||
|
||
```
|
||
main.go # 应用入口,注册所有 Controller 路由
|
||
config.yml # 配置文件
|
||
consts/ # 常量定义
|
||
controller/ # HTTP 控制器层(路由入口)
|
||
- audio/ # 音频提取接口
|
||
- video/ # 视频相关接口(拼接、剪切、分析、合并、字幕、转码、场景分割)
|
||
- common/ # 公共工具(文件上传保存)
|
||
service/ # 业务逻辑层
|
||
- video/ # 视频服务(拼接、剪切、分析、合并混音、字幕叠加、转码、场景分割)
|
||
- audio/ # 音频提取服务
|
||
- asr/ # 语音识别服务
|
||
- scene/ # 场景检测服务
|
||
- image/ # 图片处理服务
|
||
- setup/ # 初始化服务(自动检查/安装依赖)
|
||
dao/ # 数据访问层
|
||
model/ # 数据模型
|
||
- dto/ # 传输对象(请求/响应)
|
||
- entity/ # 数据库实体
|
||
resource/ # 静态资源(日志、临时文件)
|
||
sql/ # 数据库建表 SQL
|
||
scripts/ # 外部脚本(scene_detect.py)
|
||
```
|
||
|
||
### 核心功能
|
||
|
||
| 功能 | 说明 | 依赖 |
|
||
|------|------|------|
|
||
| 视频拼接 | 支持多视频拼接,提供 fast(无损 concat demuxer)和 reencode(重编码归一化)两种模式,可上传结果到 MinIO,支持同步和异步任务 | FFmpeg |
|
||
| 视频分镜剪切 | 根据分镜时间片段列表剪切视频并重新拼接输出,支持同步和异步任务 | FFmpeg |
|
||
| 视频拼接+混音 | 拼接多段视频后混入音频(支持多段),以视频时长为准自动补静音或截断,异步任务 | FFmpeg |
|
||
| 字幕叠加 | 使用 HyperFrames 将字幕/图片/动画元素渲染叠加到视频上,自动检测分辨率、拼接多视频、消音、降噪,异步任务 | FFmpeg + HyperFrames (npm) |
|
||
| 场景分割 | 使用 PySceneDetect 自动检测视频场景切分点,按场景分割为独立片段并上传,异步任务 | FFmpeg + Python3 + PySceneDetect |
|
||
| 视频转码 | 将视频转码为 H.264 + AAC + MP4 + faststart(MOOV前置),同步接口 | FFmpeg |
|
||
| 音频提取 | 从视频文件中提取音频,支持 mp3/aac/wav/ogg/flac 多种格式 | FFmpeg |
|
||
| 语音识别 | 异步语音转文字任务,基于 OpenAI Whisper | FFmpeg + Whisper |
|
||
| 视频分析 | 调用外部 Marlin-2B VLM 服务对视频进行理解分析,生成场景描述和事件切分,支持 mock 模式,异步串行处理 | FFmpeg + 外部 VLM 服务 |
|
||
|
||
### 启动初始化
|
||
|
||
- `setup` 包在 `init()` 阶段自动执行,启动时自动检查并安装缺失依赖
|
||
- 检查项:FFmpeg、Python3、PySceneDetect(scenedetect)、HyperFrames(npm 全局包)
|
||
- 每个依赖都按平台自动安装(macOS: brew, Linux: apt/apk/yum, Windows: winget/choco/scoop)
|
||
- Docker 容器环境自动检测,跳过 sudo
|
||
|
||
### API 端点
|
||
|
||
**视频拼接:**
|
||
- `POST /video/concat` - 视频拼接(URL 输入,同步)
|
||
- `POST /video/concat/async` - 视频拼接(URL 输入,异步)
|
||
- `POST /video/concat/upload` - 视频拼接(文件上传,同步)
|
||
- `POST /video/concat/upload/async` - 视频拼接(文件上传,异步)
|
||
- `GET /video/concat/task/{taskId}` - 查询异步拼接任务结果
|
||
|
||
**视频分镜剪切:**
|
||
- `POST /video/cut` - 视频分镜剪切(URL 输入,同步)
|
||
- `POST /video/cut/async` - 视频分镜剪切(URL 输入,异步)
|
||
- `GET /video/cut/task/{taskId}` - 查询异步剪切任务结果
|
||
|
||
**视频拼接+混音:**
|
||
- `POST /video/merge/async` - 创建拼接混音异步任务
|
||
- `GET /video/merge/task/{taskId}` - 查询任务结果
|
||
|
||
**字幕叠加:**
|
||
- `POST /video/caption` - 创建字幕叠加异步任务
|
||
- `GET /video/caption/{taskId}` - 查询任务结果
|
||
|
||
**场景分割:**
|
||
- `POST /video/scene-split` - 创建场景分割异步任务
|
||
- `GET /video/scene-split/task/{taskId}` - 查询任务结果
|
||
|
||
**视频转码:**
|
||
- `POST /video/transcode` - 上传视频并转码为 H.264+AAC+MP4(同步)
|
||
|
||
**视频分析:**
|
||
- `POST /video/analysis` - 创建视频分析异步任务
|
||
- `GET /video/analysis/task/{taskId}` - 查询分析任务结果
|
||
|
||
**语音识别:**
|
||
- `POST /audio/transcribe` - 创建语音转文字异步任务
|
||
- `GET /audio/task/{taskId}` - 获取转写任务详情
|
||
- `GET /audio/task/{taskId}/progress` - 获取任务进度
|
||
- `GET /audio/tasks` - 获取任务列表
|
||
|
||
### 依赖外部服务
|
||
|
||
- PostgreSQL - 数据存储
|
||
- Redis - 缓存
|
||
- Consul - 服务发现
|
||
- Jaeger - 链路追踪
|
||
- OSS/MinIO - 文件存储(通过内部 oss 微服务 `oss/file/uploadFile` 接口上传)
|
||
- FFmpeg + ffprobe - 多媒体处理
|
||
- Whisper - 语音识别
|
||
- HyperFrames (npm) - HTML/GSAP 视频渲染引擎,用于字幕叠加
|
||
- PySceneDetect - Python 场景检测库
|
||
- Marlin-2B VLM 服务 - 视频理解大模型(分析功能使用)
|
||
|
||
### 内部依赖
|
||
|
||
项目依赖内部私有公共包 `gitea.redpowerfuture.com/red-future/common`,包含 HTTP 路由注册(`http.RouteRegister`)、用户信息解析(`beans.User`)、Consul、Jaeger 等基础设施封装。Docker 构建过程中已配置访问凭证。
|
||
|
||
### Docker 镜像
|
||
|
||
多阶段构建镜像包含:
|
||
- 编译后的二进制
|
||
- FFmpeg 运行时
|
||
- Python 3 + openai-whisper(Python 版本,用于语音识别)
|
||
- 非 root 用户 `appuser` 运行
|
||
- 暴露端口 `3010`
|
||
|
||
### 架构设计
|
||
|
||
**分层架构:**
|
||
- `controller` - HTTP 入口,参数解析,调用 Service,返回响应
|
||
- `service` - 业务逻辑实现,每个功能领域一个子包
|
||
- `dao` - 数据访问层,数据库 CRUD 操作
|
||
- `model` - 数据模型,`dto` 存放请求/响应传输对象,`entity` 存放数据库实体
|
||
|
||
**设计模式:**
|
||
- 使用 GoFrame 框架的依赖注入模式
|
||
- 所有 Service 和 Controller 都使用**单例模式**(`var Xxx = new(xxxStruct)`)
|
||
- 路由注册在 `main.go` 中通过 `http.RouteRegister` 集中管理
|
||
- 临时文件处理完需要**及时清理**(使用 `defer os.Remove()` 或 `defer os.RemoveAll()`)
|
||
|
||
**异步任务处理:**
|
||
- 长时任务(拼接、剪切、合并混音、字幕叠加、场景分割、语音识别、视频分析)都支持**异步执行**
|
||
- 同步模式直接等待结果返回,异步模式创建任务后立即返回任务 ID
|
||
- 异步任务状态持久化到数据库,可通过任务 ID 查询进度和结果
|
||
- 支持回调 URL,任务完成后 POST 回调通知调用方,携带 `X-User-Info` 头透传用户信息
|
||
- 任务执行使用 goroutine 异步处理,通过 recover 捕获 panic 并更新为失败状态
|
||
- 视频拼接+混音使用信号量控制并发(通过 `merge.concurrency` 配置)
|
||
|
||
**用户身份:**
|
||
- 所有接口优先从请求头 `Authorization` / `X-User-Info` 解析用户信息
|
||
- 解析失败使用默认 `admin` / tenantId=1 用于开发和调试
|
||
- 异步任务通过 `context.WithValue` 将用户信息传递给 goroutine
|
||
|
||
**Service 层共享工具函数(`service/video` 包内):**
|
||
- `getUserFromCtx(ctx)` - 从 context 提取用户信息
|
||
- `downloadFile(ctx, url, dir)` - 下载远程文件到本地
|
||
- `uploadToMinIO(ctx, localPath)` - 通过 OSS 微服务上传文件到 MinIO
|
||
- `lookupFFmpegPath()` - 查找 FFmpeg 可执行文件路径(优先配置路径,回退系统 PATH)
|
||
- `getVideoResolution(ctx, path)` - 用 ffprobe 获取视频分辨率
|
||
- `getVideoRealDuration(ctx, path)` - 用 ffprobe 获取视频时长(float64秒)
|
||
- `getVideoDurationStr(ctx, path)` - 获取视频时长可读字符串(m:ss格式)
|
||
- `cleanupFiles(paths)` - 批量清理临时文件
|
||
|
||
### 配置
|
||
|
||
主要配置在 `config.yml`:
|
||
|
||
**Server:**
|
||
- `server.address` - 监听地址(默认 `:3010`)
|
||
- `server.clientMaxBodySize` - 上传文件大小限制(默认 `200MB`)
|
||
|
||
**限流:**
|
||
- `rate.limit` - 每秒请求限制(默认 200)
|
||
- `rate.burst` - 突发请求允许量(默认 300)
|
||
|
||
**FFmpeg:**
|
||
- `ffmpeg.path` - FFmpeg 可执行文件路径,留空则从 PATH 自动查找
|
||
- `ffmpeg.temp_dir` - 临时文件目录(存放上传的视频和处理输出)
|
||
|
||
**视频分析:**
|
||
- `analysis.video_dir` - 视频永久存储目录(按 taskId 子目录组织)
|
||
- `analysis.caption_url` - Caption 接口地址
|
||
- `analysis.caption_timeout` - 单次调用超时(默认 `30m`)
|
||
- `analysis.max_new_tokens` - 传递给 Caption 接口的参数
|
||
- `analysis.mock_caption` - 是否启用 mock 模式(true: 返回模拟数据,false: 真实调用)
|
||
|
||
**视频拼接+混音:**
|
||
- `merge.concurrency` - 并发数控制(默认 1,串行处理)
|
||
|
||
**HyperFrames 字幕叠加:**
|
||
- `hyperframes.render_timeout` - 渲染超时时间(分钟,默认 30)
|
||
- `hyperframes.headless` - 是否启用 headless 模式(默认 true)
|
||
|
||
**外部服务:**
|
||
- `database` - PostgreSQL 数据库配置
|
||
- `redis` - Redis 配置
|
||
- `consul` - Consul 服务发现配置
|
||
- `jaeger` - Jaeger 链路追踪配置
|
||
- `filePrefix` - OSS/MinIO 文件访问地址前缀 |