Sign inSign up

skytan/ttfn

By skytan

•Updated 3 months ago

Image
0

730

skytan/ttfn repository overview

⁠TTFN (FNTV Proxy)

飞牛影视 302 代理与起播延迟优化工具 - 自动解析 .strm 文件并重定向至网盘直链,支持用户身份识别。

  • 基于飞牛影视0.9.3及后续版本测试
  • 已测试 115网盘、夸克网盘 等通过 Alist 挂载生成的 .strm 虚拟视频文件

⁠🌟 功能特性

  • ✅ 透明代理:无缝代理飞牛影视服务,对普通流媒体和 API 请求零干扰。
  • ✅ 起播性能优化 (异步预解析):在客户端获取播放信息(PlaybackInfo)的瞬间,后台异步读取 .strm 并提前解析出网盘直链写入缓存,实现客户端起播 0 延迟。
  • ✅ 高效直链解析:解析重定向时优先采用 HTTP HEAD 请求,避免云盘服务端缓冲/下载视频大文件,使得跳转地址获取速度大幅提升。
  • ✅ 用户身份识别:自动从客户端请求(Headers/Query)中提取 Token,反查飞牛影视后端获取对应的用户名,并在日志中记录(如:🎬 [用户: 张三] 拦截到视频流请求)。
  • ✅ 网络鲁棒性:为直链解析增加 5 秒超时限制,防止异常链接无限期挂起。
  • ✅ 优雅关闭与热重载:支持 SIGINT/SIGTERM 优雅关闭清理,支持基于轮询(Docker 友好)的 config.yaml 配置文件热重载。

⁠🚀 快速开始

⁠1. 创建配置文件 config.yaml
# 代理监听地址
listen: ":28005"

# 飞牛影视服务真实地址
target: "http://127.0.0.1:8005"

# 日志级别: trace / debug / info / warn / error
# 生产环境推荐 info,排查问题推荐 debug
log_level: "info"

# 日志目录(trace/debug级别时写入日志文件,info级别可省略)
log_dir: "./logs"

# 直链缓存过期时间(分钟),默认1小时
cache_ttl: 60
⁠2. Docker Compose 部署配置
services:
  ttfn:
    image: skytan/ttfn:latest
    container_name: ttfn
    ports:
      - "28005:28005"
    volumes:
      # 挂载strm文件目录(根据实际路径修改,确保容器内外路径完全一致)
      - /vol00/strm:/vol00/strm:ro
      - /vol01/strm:/vol01/strm:ro
      # 挂载配置文件
      - ./config.yaml:/app/config.yaml:ro
    environment:
      # 配置文件路径
      - CONFIG=/app/config.yaml
    restart: unless-stopped

⁠⚙️ 环境变量

变量说明默认值
CONFIG配置文件路径./config.yaml
TZ时区Asia/Shanghai
FNTV_CACHE_TTL直链缓存过期时间(分钟),优先级高于配置文件的 cache_ttl60

⁠📊 日志说明

级别输出位置说明
trace文件最详细,记录完整请求/响应头及 Body(仅限排查严重鉴权问题使用)
debug控制台 + 文件记录所有请求、响应及直链后台异步预解析详情
info控制台只输出关键信息,包括用户身份和重定向跳转行为(推荐生产环境)
warn控制台只输出警告和错误
error控制台只输出错误
⁠正常播放日志输出示例(Info 级别):
[2026-06-28 12:50:00] INFO: 🎯 [用户: 小明] 拦截到 PlaybackInfo 接口
[2026-06-28 12:50:00] INFO: 📄 缓存.strm: MediaSourceId=1a2b3c4d..., ItemId=064d9e7c...
[2026-06-28 12:50:01] INFO: 💾 [异步预解析] 成功缓存直链 (MediaSourceId: 1a2b3c4d...)
[2026-06-28 12:50:02] INFO: 🎬 [用户: 小明] 拦截到视频流请求: /emby/videos/064d9e7c.../stream.mp4
[2026-06-28 12:50:02] INFO: ✅ [用户: 小明] 从缓存获取直链: https://quark-cdn-link.com/file/...

⁠📂 项目结构

ttfn/
├── cmd/
│   └── main.go                 # 入口,负责初始化、优雅退出和配置监听
├── internal/
│   ├── cache/
│   │   └── cache.go            # 直链缓存与媒体源物理路径映射管理 (双向索引)
│   ├── config/
│   │   └── config.go           # 基于轮询的配置热加载管理
│   ├── handler/
│   │   ├── playback.go         # 拦截 PlaybackInfo 触发缓存并进行异步预解析
│   │   ├── resolver.go         # 基于 HEAD 降级 GET 的直链解析器
│   │   ├── stream.go           # 拦截播放流返回 302 重定向
│   │   └── user.go             # 提取鉴权 Token 并反查飞牛后端对应用户名
│   ├── logger/
│   │   └── logger.go           # 多级日志组件
│   └── proxy/
│       └── server.go           # 基于 httputil.ReverseProxy 的代理核心服务
├── config.yaml                 # 默认配置文件
├── docker-compose.yml          # Compose 部署配置
├── Dockerfile                  # 容器镜像构建文件
└── README.md                   # 说明文档

⁠🛠️ 工作原理

1. 客户端(用户) ──(请求 PlaybackInfo)──> [TTFN 代理] ──> [飞牛影视后端]
2. [TTFN 代理] <──(返回 PlaybackInfo JSON)── [飞牛影视后端]
   └─ 📌 拦截并提取 .strm 物理路径
   └─ 📌 提取鉴权 Token 反查并缓存播放用户名
   └─ ⚡ [异步子协程] 读取 .strm 并向云盘发起 HEAD/GET 解析直链,提早写入直链缓存
3. 客户端(用户) ──(请求播放流 /stream.mp4)──> [TTFN 代理]
   └─ 🚀 直接命中直链缓存,瞬间返回 302 重定向到云盘直链
4. 客户端(用户) ──(直接连接网盘 CDN 播放)──> [云盘服务]

⁠❓ 常见问题与排查

⁠Q: 点击播放后依然会卡顿数秒?
  1. 飞牛首次探测:如果是新导入且从未在飞牛里播放/扫描过的视频,飞牛影视在首次生成 PlaybackInfo 时会强制调用内置的 ffprobe 探测文件信息。这会直接阻塞飞牛后端。建议让飞牛媒体库的首次完整扫描完成,或者使用媒体信息预提取工具将元数据写入飞牛数据库。
  2. .strm 文件保存在慢速存储:请尽量将 .strm 文件放置在 NAS 本地 SSD 或本地硬盘,避免将 .strm 本身放在 rclone 网络挂载盘上,这会导致读取文件文本本身产生明显延迟。
⁠Q: 日志中为什么显示 [用户: 未知用户]?
  1. 客户端可能使用了非标准的鉴权方式。此时您可以将 log_level 临时调整为 trace,查找 /PlaybackInfo 请求头中包含了哪些鉴权字段(如 Authorization 里的其他关键字),修改 internal/handler/user.go 中的 extractToken 函数添加识别。
  2. 请检查飞牛后端的服务网络连通性,确保代理能够通过配置的 target 顺利请求到 /emby/Users/Me。

Tag summary

Content type

Image

Digest

sha256:bf400095e…

Size

9.5 MB

Last updated

3 months ago

docker pull skytan/ttfn