# telegram-thumbs **Repository Path**: DaTree/telegram-thumbs ## Basic Information - **Project Name**: telegram-thumbs - **Description**: 扫描本地目录视频,自己弄的简单的扫描库,方便整理自己下载的电影。支持硬件编解码播放。 - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-20 - **Last Updated**: 2026-09-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Telegram 视频片库管理系统 (telegram-thumbs) 自动监听 Telegram Desktop 下载目录,把新视频**自动入库、生成缩略图、构建影视墙**,并提供 **HLS 按需分片硬转码播放**的完整片库系统。 ## 功能特性 - **自动监听入库**:watchdog 实时监听 `F:\Downloads\Telegram Desktop`(含子目录),新视频 8 秒内自动完成:扫描 → 截图 → 入库;另有 60 秒全量重扫兜底 - **路径 MD5 去重**:以文件路径 MD5 作为唯一索引,毫秒级查重,0 源文件读 IO - **多 Part 剧集归集**:`xxx_part1/part2/part3` 自动归为同一部剧,生成"第 N 集"分集列表,影视墙只显示一张卡片 - **自动缩略图**:每个视频自动截取 5 张(按日期分目录 `thum//_N.jpg`),支持手动重新截图、封面上传 - **自动中文字幕**(2026-09-20 新增): - **远程算力**:ASR(faster-whisper large-v3 float16)+ 翻译(Qwen2.5-14B GGUF q4,llama.cpp CUDA)默认部署在 **RTX 3090 24G 服务器**(10.10.18.48),本地 8G 显卡零负担 - 批量队列:新视频自动入队 / 现有视频按入库时间倒序补全,失败自动重试,断点续跑 - 外挂 SRT:源文件旁生成同名 `.srt`(**不改动源文件**),播放器内置中文字幕轨道与开关 - 中文视频自动跳过翻译(省算力);无人声视频写空字幕标记完成,不反复重试 - **后端可切换**(`application/subtitle/config.py`,全环境变量覆盖): - `SUBTITLE_ASR_BACKEND=remote`(默认,走 3090 服务器)/ `local`(本机 faster-whisper) - `SUBTITLE_TRANSLATE_BACKEND=remote_llamacpp`(默认,3090 服务器)/ `local_llamacpp`(本机 7B)/ `local_ollama` / `cloud_openai`(小米 MiMo 等 OpenAI 兼容云端) - 切换后端流水线代码零改动 - **影视墙 Web 端**:搜索 / 分组(自动+手动)/ 标签 / 演员 / 精品收藏,多 Part 剧集切换 - **HLS 按需分片硬转码播放**(核心): - NVENC 硬转码,GPU 闸排队 + 并发锁去重,失败自动降级 CPU - m3u8 动态生成:已转码分片回填真实时长,未转码用 I 帧估算,EXTINF 累加恒等于源总时长(进度条完整) - 拖动到未解码区自动等待生成(hold 机制),不中断播放 - 会话预取(当前段+1/+2 提前转码)、磁盘缓存 LRU/TTL 双轨清理 - 分片/元数据双层缓存:m3u8 秒回,杜绝播放卡死 - **播放日志**:全链路落盘 `services_logs/play.log`,便于排查 ## 技术栈 | 层 | 技术 | | --- | --- | | 后端 | Python 3.11 + Flask + SQLAlchemy ORM | | 数据库 | MySQL 8(`telegram_thum`) | | 转码 | FFmpeg(NVENC 硬编,CPU 降级) | | 监听 | watchdog | | 前端 | Vue(`ui/`,nginx 8899 托管) | | 部署 | WinSW Windows 服务(API 8000)+ nginx(前端 8899) | ## 目录结构 ``` telegram-thumbs/ ├── run.py # 统一启动入口 (python run.py) ├── application/ # 应用代码 │ ├── api.py # Flask REST API + 启动/拉起 watcher │ ├── watcher.py # 目录监听 (watchdog + 60s 兜底, 单实例互斥) │ ├── thumbs.py # 扫描分组 / 路径MD5 / 缩略图生成 │ ├── db.py # SQLAlchemy ORM 模型与会话 │ ├── config.py # 全局配置 (缓存/鉴权/队列参数) │ ├── transcoder.py # FFmpeg 转码封装 (NVENC/CPU) │ ├── seg_worker.py # 单分片转码 worker │ ├── gpu_queue.py # GPU 闸队列 │ ├── hls_router.py # 分片路由 (缓存命中/转码/缓存失效) │ ├── hls_m3u8.py # 动态 m3u8 生成 (I帧切分/时长累加) │ ├── media_meta.py # 视频元数据扫描 (ffprobe + I帧) + 后台预扫描 │ ├── cache_mgr.py # 磁盘缓存 LRU/TTL 清理 │ ├── prefetch.py # 会话预取 (拖动取消) │ ├── play_log.py # 播放链路落盘日志 │ └── subtitle/ # 自动中文字幕子系统 (2026-09-20) │ ├── config.py # ASR/翻译后端/队列配置 (云端预留) │ ├── asr.py # faster-whisper 语音识别 (子进程显存隔离) │ ├── translator.py # 翻译后端抽象 (llama.cpp / ollama / 云端预留) │ ├── srt.py # SRT 生成/校验 (BOM 写入, 源文件旁外挂) │ ├── pipeline.py # 单视频流水线 (抽音频→ASR→翻译→SRT) │ └── queue.py # 批量队列 (时间倒序/断点续跑/单 GPU 串行) │ └── db/ │ └── init/init.sql # 数据库结构备份 (仅结构, 无数据) ├── tests/ # 测试/诊断脚本 (test_*.py) ├── tools/ # 迁移/工具脚本 (migrate_*, remux_hvc1) ├── ui/ # 前端 (Vue, nginx 托管, 不动) ├── services_logs/ # 运行日志 (thumbs/play/watcher/api) ├── telegram-thumbs-service.xml # WinSW 服务配置 ├── start_api.bat / start_watcher.bat / start_nginx.bat └── requirements.txt ``` ## 快速开始 ### 1. 环境 - Python 3.11(conda 环境 `telegram-thumbs`,`C:\ProgramData\miniconda3\envs\telegram-thumbs\python.exe`) - FFmpeg(含 NVENC 支持,路径见 `application/thumbs.py` / `config.py`) - MySQL 8(`10.10.18.48:4406`,库 `telegram_thum`) ```bash pip install -r requirements.txt # 或使用 conda env telegram-thumbs ``` ### 2. 初始化数据库 ```bash mysql -h10.10.18.48 -P4406 -uroot -p < application/db/init/init.sql ``` ### 3. 启动 ```bash python run.py # 启动 API (0.0.0.0:8000),自动拉起 watcher python run.py --no-watch # 不拉起 watcher(由其他方式管理时用) ``` 或作为 Windows 服务(推荐): ```bash telegram-thumbs-service.exe install sc start telegram-thumbs ``` 前端(nginx 8899)由 `start_nginx.bat` 启动;登录:`admin / Xg@2020+`。 ## 播放架构简述 ``` 浏览器 (hls.js) → /api/hls///index.m3u8 → 动态 m3u8 (I帧估算时长) → /api/hls///seg_NNNNN.ts → 缓存命中直出 → 未命中: GPU队列排队 → NVENC转码(CPU降级) → 落盘缓存 → 返回 后台: media_meta 预扫描 I 帧 / prefetch 会话预取 / cache_mgr LRU+TTL 清理 ``` - 清晰度:480p / 720p(`config.QUALITY_LEVELS`) - 缓存根:`F:/Downloads/Telegram Desktop trans/_seg_cache` - 日志:`services_logs/play.log`(每分片请求一行,含 sid/耗时/转码方式) ## 主要 API | 方法 | 路径 | 说明 | | --- | --- | --- | | POST | `/api/auth/login` | 登录获取 token | | GET | `/api/movies` | 片库列表(分页/搜索/筛选/排序) | | GET | `/api/movies/` | 详情(多 Part 分集列表) | | DELETE | `/api/movies/` | 删除(源文件+截图+DB) | | POST | `/api/movies//rethumb` | 重新截图 | | GET | `/api/groups` `/api/tags` `/api/actors` | 分组/标签/演员聚合 | | GET | `/api/hls///index.m3u8` | HLS 播放列表 | | GET | `/api/hls///seg_.ts` | 分片(自动转码) | | GET | `/api/hls/queue` `/api/hls/cache` `/api/hls/prefetch` | 运行观测 | | GET | `/api/subtitles/status` | 字幕队列/库内覆盖统计 | | GET | `/api/subtitles//.vtt` | WebVTT 字幕(播放器轨道) | | GET | `/api/subtitles//.srt` | 外挂 SRT 下载 | | POST | `/api/subtitles/scan` | 批量入队(时间倒序,`?body={limit,force}`) | | POST | `/api/subtitles//enqueue` | 单视频立即生成 | | GET | `/api/health` | 健康检查 | 认证:除登录/健康检查外,需 `Authorization: Bearer `(或 Cookie)。 ## 数据库 (telegram_thum) | 表 | 说明 | | --- | --- | | `video_entries` | 片库条目(路径MD5主键、分集文件列表、缩略图日期、标签演员、`sub_status` 字幕状态) | | `video_meta` | 视频元数据(时长/分辨率/编码/I帧时间戳列表 `MEDIUMTEXT`) | | `seg_meta` | 分片元数据(缓存路径/真实时长/状态,HLS 播放支撑) | | `subtitle_queue` | 字幕任务队列(md5+part 唯一键、状态/重试/错误、断点续跑) | ## 自动中文字幕(使用说明) ### 架构(默认:远程 3090 服务器,本地零推理负担) ``` 本地 (RTX3060 8G) 远程服务器 (RTX3090 24G, 10.10.18.48) ┌──────────────────────────┐ ┌──────────────────────────────┐ │ pipeline (队列 worker) │ wav 上传 │ ASR 服务 :8123 │ │ ffmpeg 抽音轨 → .wav ────┼────────────▶│ faster-whisper large-v3 │ │ 文本分段 ────────────────┼────────────▶│ LLM 服务 :8090 │ │ SRT 落盘 (源文件旁) │ OpenAI 兼容 │ llama-server Qwen2.5-14B │ └──────────────────────────┘ └──────────────────────────────┘ ``` ### 服务器部署(已落地 /home/xg/subtitle-trans/) ``` ├── conda env telegram-thumbs/ # Python 3.11 (uv 安装), faster-whisper + flask ├── server.py # ASR 服务 (POST /asr, multipart wav) — 端口 8123 │ # word_timestamps: 字幕按词级时间戳收尾, 静音处自动消失 ├── models/ │ ├── whisper-large-v3/ # ASR 模型 (ModelScope 下载) │ └── qwen2.5-14b-instruct-q4_k_m-0000{1,2,3}-of-00003.gguf # LLM 模型 └── bin/llama_x/.../llama-server # llama.cpp CUDA 二进制 (b11063) ``` 启动(服务器上): ```bash cd /home/xg/subtitle-trans nohup conda env telegram-thumbs/bin/python server.py > services_asr.log 2>&1 & # ASR :8123 export LD_LIBRARY_PATH=$HOME/subtitle-trans/bin/cudart_x/cudart-llama-b11063-bin-ubuntu-cuda-12.8-x64:$LD_LIBRARY_PATH nohup ./bin/llama_x/llama-b11063/llama-server -m models/qwen2.5-14b-instruct-q4_k_m-00001-of-00003.gguf \ --host 0.0.0.0 --port 8090 --n-gpu-layers 99 -c 8192 --no-webui > services_llm.log 2>&1 & # LLM :8090 ``` ### 后端切换(环境变量,流水线代码零改动) | 环境变量 | 取值 | 说明 | | --- | --- | --- | | `SUBTITLE_ASR_BACKEND` | `remote`(默认)/ `local` | ASR 走 3090 服务器 / 本机 | | `SUBTITLE_TRANSLATE_BACKEND` | `remote_llamacpp`(默认)/ `local_llamacpp` / `local_ollama` / `cloud_openai` | 翻译后端 | | `SUBTITLE_REMOTE_ASR_URL` | `http://10.10.18.48:8123` | 远程 ASR 服务地址 | | `SUBTITLE_REMOTE_LLM_URL` | `http://10.10.18.48:8090` | 远程 LLM 服务地址 | | `SUBTITLE_CLOUD_BASE_URL` / `CLOUD_API_KEY` / `CLOUD_MODEL` | 小米 MiMo 等 | 云端 OpenAI 兼容 | ### 触发与监控 - **自动**:API 启动即拉起字幕 worker;`POST /api/subtitles/scan` 按入库时间倒序把无字幕视频全部入队;watcher 检测到新文件自动入队 - **单个**:`POST /api/subtitles//enqueue` - 进度:`GET /api/subtitles/status`;日志 `services_logs/play.log`(`[subtitle.*]` 前缀) 显存:本地 8G 无需加载任何模型;服务器 24G 上 whisper float16(~4G)+ 14B q4(~10G)共存,余量 6G+。 结构备份:`application/db/init/init.sql`(仅结构,无数据;`DROP TABLE` 会重建,注意已有数据)。