forked from xingluo/GMapiServer
This branch is 6 commits behind xingluo/GMapiServer:main
GMapiServer
GMapiServer 是一个基于 Python 和 Flask 构建的高性能 API 服务器,支持通过 URL 输入文件并输出下载链接,提供同步和异步两种处理模式。内置缓存自动清理机制(默认保留 2 小时),支持多种工具接口调用,包括实时任务状态查询和视频帧处理功能。
🚀 项目简介
GMapiServer 是一个轻量级、模块化的 API 服务框架,旨在为开发者提供以下核心功能:
- URL 输入与输出:支持通过 URL 提交文件,返回生成文件的下载链接。
- 异步处理:任务在后台异步执行,不阻塞主进程,提升服务器并发性能。
- 自动缓存清理:内置定时清理机制,自动删除过期的缓存文件(包括输出文件),默认保留时间 2 小时。
- 多工具接口集成:集成 FFmpeg 和 Sanjuuni 工具接口,支持在线调用。
- 实时任务状态:提供任务状态查询接口,支持日志实时推送。
- 视频帧提取:支持从视频中提取指定分辨率、帧率的图片帧,可打包为二进制格式。
- 硬件加速支持:支持 NVIDIA CUDA、Intel QSV、VA-API、树莓派 v4l2m2m 等硬件加速方式。
🛠️ 技术栈
- 编程语言: Python 3.10+
- Web 框架: Flask
- 异步处理: 基于 threading
- 缓存清理: 定时任务
- 依赖管理: pip
- 视频处理: FFmpeg (支持硬件加速)
🧩 支持的接口
1. FFmpeg 工具接口
- 功能: 在线调用 FFmpeg 工具进行视频/音频处理(如转码、裁剪、合并等)。
- 接口文档: https://www.liulikeji.cn/archives/FFmpegApi
- 同步接口: POST /api/ffmpeg
- 异步接口: POST /api/ffmpeg/async
2. Sanjuuni 工具接口
- 功能: 在线调用 https://github.com/MCJack123/sanjuuni/tree/master(具体功能需参考其官方文档)。
- 接口文档: https://www.liulikeji.cn/archives/SanjuuniApi
- 同步接口: POST /api/sanjuuni
- 异步接口: POST /api/sanjuuni/async
3. 视频帧提取接口
- 功能: 从视频中提取指定分辨率、帧率的图片帧,支持强制分辨率调整和填充,支持B站BV号。
- 异步接口: POST /api/video_frame/async
- 参数:
- video_url: 视频文件 URL (或使用 video_bv 参数替代)
- video_bv: B站视频BV号 (自动转换为URL)
- w: 输出宽度
- h: 输出高度
- fps: 输出帧率 (默认: 30)
- force_resolution: 是否强制调整分辨率 (默认: false)
- pad_to_target: 是否填充到目标分辨率 (默认: false)
- pix_fmt: 输出像素格式,可选
pal8或rgb24(默认:pal8)
- 返回示例:
{
"task_id": "abc12345",
"status_url": "http://localhost:5000/api/task/abc12345",
"message": "任务已创建,请使用状态URL查询进度"
}
- 实时任务状态响应(处理中):
{
"task_id": "abc12345",
"status": "running",
"progress": 50,
"create_time": 1770393314.1262555,
"start_time": 1770393314.1262555,
"end_time": null,
"type": "video_frame",
"result": {
"audio_urls": {
"audio_dfpwm_url": "/frames/abc12345/audio.dfpwm",
"audio_dfpwm_left_url": "/frames/abc12345/audio_left.dfpwm",
"audio_dfpwm_right_url": "/frames/abc12345/audio_right.dfpwm"
},
"current_frames": 180,
"total_frames": 6059,
"output_resolution": {"w": 640, "h": 360}
},
"total_logs": 15,
"last_index": 15,
"new_logs": ["日志1", "日志2"]
}
- 任务完成时结果:
{
"task_id": "abc12345",
"status": "completed",
"progress": 100,
"create_time": 1770393314.1262555,
"start_time": 1770393314.1262555,
"end_time": 1770393391.1024792,
"type": "video_frame",
"result": {
"audio_urls": {
"audio_dfpwm_url": "/frames/abc12345/audio.dfpwm",
"audio_dfpwm_left_url": "/frames/abc12345/audio_left.dfpwm",
"audio_dfpwm_right_url": "/frames/abc12345/audio_right.dfpwm"
},
"duration_seconds": 303.019,
"current_frames": 6059,
"total_frames": 6059,
"fps": 20,
"output_resolution": {"w": 640, "h": 360}
},
"total_logs": 164,
"last_index": 164,
"new_logs": ["最后日志"]
}
4. 异步任务状态查询
- 功能: 查询异步任务状态和进度,支持日志实时推送。
- 接口: GET /api/task/<task_id>
- 返回字段:
- status: 任务状态(pending/running/completed/error)
- progress: 进度百分比
- new_logs: 新增的日志条目
- result: 完成后的结果(包含下载URL)
- error: 错误信息(如果状态为error)
5. 帧打包接口
- 功能: 将多个帧图片打包为二进制格式,便于批量下载。
- 接口:
GET /api/framepack?<task_id>-<start>-<end>(推荐)POST /api/framepack(兼容旧方式)
- 参数:
- 新方式:
task_id: 视频帧任务IDstart: 起始帧(从1开始)end: 结束帧(包含)
- 旧方式:
urls: 帧图片URL列表,格式为/frames/<job_id>/<filename>.png
- 新方式:
- 返回: 二进制流,格式为帧数(4字节) + 各帧数据
6. 文件下载接口
- 功能: 下载处理完成的文件。
- 接口: GET /download/<file_id>/
7. 任务列表查询
- 功能: 列出所有任务状态(调试用)。
- 接口: GET /api/tasks
8. 健康检查
- 功能: 服务健康检查。
- 接口: GET /health
📦 部署与使用
1. 安装依赖
pip install -r requirements.txt
2. 配置文件
编辑 config.json 配置各项参数:
{
"streaming": {
"enabled": true,
"buffer_size": 8192,
"chunk_delay_ms": 0
},
"server": {
"port": 5000,
"debug": false,
"threaded": true
},
"cleanup": {
"interval_hours": 1,
"retention_hours": 2,
"download_cache_max_mb": 500,
"video_cache_max_mb": 2000,
"cache_retention_hours": 2
},
"logging": {
"level": "INFO",
"file_path": "data/server.log"
},
"hwaccel": {
"enabled": true,
"method": "auto"
},
"video_download": {
"limit_resolution": true,
"max_resolution": "720p",
"preferred_codec": "h264"
}
}
配置说明
| 配置项 | 说明 | 默认值 |
|---|---|---|
hwaccel.enabled |
是否启用硬件加速 | true |
hwaccel.method |
硬件加速方式(auto/cuda/vaapi/qsv/v4l2m2m/drm) | auto |
video_download.limit_resolution |
是否限制下载分辨率 | true |
video_download.max_resolution |
最大下载分辨率(480p/720p/1080p/best) | 720p |
video_download.preferred_codec |
首选视频编码(h264/h265/av1/vp9/auto) | h264 |
3. 启动服务器
# 方式1:直接启动
python main.py
# 方式2:使用启动脚本
python start_server.py
# 方式3:指定端口
python main.py --port 5000
4. 异步任务使用示例
创建异步FFmpeg任务
curl -X POST http://localhost:5000/api/ffmpeg/async \
-H "Content-Type: application/json" \
-d '{
"input_url": "http://example.com/input.mp4",
"output_format": "mp4",
"args": ["-c:v", "libx264", "-crf", "23"]
}'
查询任务状态
curl http://localhost:5000/api/task/<task_id>
5. 指定公网地址
在相应工具模块中配置下载URL:
# sanjuuni_utils.py
return {
'status': 'success',
'download_url': f"http://ffmpeg.liulikeji.cn/download/{output_id}/{output_filename}",
'file_id': output_id,
'temp_dir': temp_dir
}
# ffmpeg_utils.py
return {
'status': 'success',
'download_url': f"http://ffmpeg.liulikeji.cn/download/{output_id}/{output_filename}",
'file_id': output_id,
'temp_dir': temp_dir
}
🔧 硬件加速配置
支持的硬件加速方式
| 加速方式 | 适用平台 | 说明 |
|---|---|---|
| cuda | NVIDIA GPU | 需要 NVIDIA 显卡和 CUDA 工具包 |
| vaapi | Intel/AMD Linux | 需要支持 VA-API 的显卡 |
| qsv | Intel Quick Sync | Intel 核显专用 |
| videotoolbox | macOS | Apple 芯片专用 |
| v4l2m2m | 树莓派/嵌入式 Linux | 支持 H.264 编码 |
| drm | Linux DRM/KMS | 树莓派官方系统推荐 |
| mmal | 树莓派(旧版) | 树莓派传统硬件加速 |
| vdpau | NVIDIA Linux | NVIDIA VDPAU 加速 |
验证硬件加速
# 检查可用编码器
ffmpeg -encoders | grep v4l2m2m
# 测试硬件编码
ffmpeg -i input.mp4 -c:v h264_v4l2m2m output.mp4
# 检查硬件加速方式
ffmpeg -hwaccels
⏰ 自动缓存清理配置
- 默认保留时间: 2 小时
- 自定义配置: 在
config.json中修改
🔄 缓存与恢复机制(2026-05 更新)
1. 持久化存储
- 任务与缓存索引会写入
cache_state/state.json。 - 服务重启后自动恢复任务、文件注册表和视频帧缓存索引。
2. 视频帧任务去重(全参数匹配)
/api/video_frame/async会对请求计算签名(包含 URL、分辨率、fps、pix_fmt、force_resolution、pad_to_target 等)。- 若签名匹配到已有任务:
- 任务
pending/running:直接返回已有task_id。 - 任务
completed且缓存有效:复用已有task_id并重置过期计时。 - 任务
error/ 缓存失效 / 缓存目录缺失:自动新建task_id重新转换。
- 任务
3. 重启中断识别
- 启动时会将上次
pending/running的任务标记为“因服务器重启中断”。 - 这类任务不会被复用,同参数新请求会重新创建任务。
4. 看门狗式缓存续期(2 小时)
- 视频帧缓存采用看门狗语义:每次相关访问都会将过期时间重置为
当前时间 + 2小时。 - 相关访问包括:
/api/video_frame/async命中已有任务/api/framepack请求了该job_id的帧- 视频帧任务转换完成后的结果写回
- 若超过 2 小时没有相关访问,则按清理策略过期。
5. NoDelete 保护
- 清理线程会检测
frames/<task_id>/NoDelete文件。 - 若存在该文件:
- 跳过该目录清理
- 并重置该任务缓存计时器(
now + 2h)
6. 双语日志
ffmpeg、sanjuuni、video_frame的业务日志已统一为中英双语格式:中文 | English。
🔥 视频帧实时进度功能
GMapiServer 的视频帧提取功能支持实时进度跟踪,让客户端可以在任务处理过程中实时获取已生成的帧并进行下载。
优势特性
- 减少等待时间: 客户端无需等待整个视频处理完成
- 并行下载: 可以在转换过程中并行下载已生成的帧
- 实时反馈: 用户可以看到实时处理进度和日志
- 资源优化: 避免了"堵车"效应,提高系统并发能力
使用建议
- 客户端可以轮询
/api/task/<task_id>接口获取最新状态 - 通过检查
result.current_frames与result.total_frames判断转换进度 - 音频文件可以立即下载(音频处理优先级更高)
🔧 异步任务处理流程
- 任务创建: 客户端提交任务请求,服务器返回任务ID和状态查询URL
- 后台处理: 任务在独立线程中执行,不阻塞主进程
- 状态查询: 客户端可轮询状态接口获取任务进度和实时日志
- 结果获取: 任务完成后可通过状态接口或文件下载接口获取结果
- 自动清理: 任务结果文件在指定时间后自动清理
⚠️ 注意事项
- 文件合法性: 请确保上传文件符合法律法规,不得用于非法用途。
- 缓存文件: 系统会自动清理过期文件,请及时下载生成的输出文件。
- 异步任务: 任务状态已支持持久化恢复;但重启前处于运行中的任务会被标记为中断,需要重新发起。
- 资源限制: 视频帧提取和转码操作可能消耗较多CPU和内存资源。
- 树莓派注意: 硬件解码可能不可用,但硬件编码(h264_v4l2m2m)可用,性能提升约3倍。
📝 贡献与反馈
欢迎提交 Issue 或 Pull Request!
如有问题,请联系:[xingluo01@liulikeji.cn] 或 [qq:180877430]
📁 项目结构
GMapiServer/
├── main.py # 主程序入口
├── start_server.py # 启动脚本(含运行库检查)
├── config.py # 配置管理
├── config.json # 配置文件
├── shared_utils.py # 共享工具函数
├── ffmpeg_utils.py # FFmpeg处理模块
├── sanjuuni_utils.py # Sanjuuni处理模块
├── video_frame_utils.py # 视频帧提取模块
├── file_cleanup.py # 文件清理模块
├── hwaccel_detect.py # 硬件加速检测模块
├── lib_downloader.py # 运行库下载器
├── logging_config.py # 日志配置
├── logo.py # Logo输出
├── requirements.txt # 依赖包列表
├── test/ # 测试工具目录
│ └── decode_performance_test.py # 性能测试脚本
├── lib/ # 本地运行库
│ ├── ffmpeg/
│ └── sanjuuni/
├── data/ # 数据目录
│ ├── ffmpeg/
│ ├── sanjuuni/
│ └── videoframe/
└── README.md # 项目说明文档
Languages
Python
100%