Skip to content

Emby 协议兼容 ​

播放节点对外说 Emby 协议:现有生态客户端填地址与账号即可用,用户侧零改造。 在「能用」之外,这一页重点讲接口链路做了哪些加速与缓存——浏览列表、海报图片、 启播字节三条热路径各有独立缓存层,另有直链复用防云盘风控。面向选型评估的站长与调优性能的运维者。

1 个协议
Emby 兼容协议面;其他协议返回 503
3 层缓存
查询结果 Redis / 节点图片盘 / 启播字节缓存
0 改造
Infuse、VidHub、Sviewer、Fileball 等直接用
主动失效
查询缓存不过期,库变更后即清对应键

能做什么 ​

  • 用任意 Emby 生态客户端浏览媒体库:库列表、最新入库、继续观看与下一集(Resume / NextUp 是真实实现,不是空壳)、条目详情、剧集季/集、搜索(服务端按标题匹配,无独立 /Search 端点)。
  • 直接起播与拖动进度条:文件流经 HTTP Range 原样输出,服务端不加工;seek 能力取决于客户端。
  • 选字幕、选音轨:文本字幕走协议标准端点原样下发;内嵌字幕与多音轨由客户端对同一路字节流自行处理。
  • 标记已看 / 收藏 / 删除观影历史:状态持久化在服务端,与门户「观影记录」互通; 进度到 90% 自动记为已完成(追剧的「下一集」就是这么排出来的)。
  • 播放开始、进度、结束按协议会话上报:这些记录是播放报表的数据来源,有效观看还会自动续期账号到期时间。
  • 门户「客户端配置」给出该用户的专属播放地址与用户名,还能一键生成带凭据的导入链接。

接入三步 ​

01
用户取地址
登录门户 →「客户端配置」,复制播放入口地址与用户名(在线/离线徽标可先点健康探测确认)。
02
客户端添加服务器
选 Emby 服务器,填地址与账号。多个入口就配多台,用户可自行启用/停用。
03
浏览并播放
首次列库与拉海报最快在毫秒级——见下面的缓存层;视频以直连播放,能否出画取决于客户端对该容器与编码的支持。

一条请求由谁处理 ​

播放节点(play-agent)是协议入口,但不同请求族由不同角色实现:

请求族代表端点谁在服务
视频流Videos/{id}/stream.*、original播放节点本地:读云盘/本地盘字节,配 VFS 缓存与限速;多版本按 MediaSourceId 切换
图片Items/{id}/Images/*(Primary / Backdrop / Logo)播放节点本地图片缓存,未命中回源媒体或账号服务
浏览与检索Views、Items(含搜索参数)、Resume / Latest / NextUp、Shows/{id}/Seasons、Episodes、Similar、PlaybackInfo、字幕端点媒体服务(Redis 结果缓存加速)
账号与会话Users/AuthenticateByName、PlayedItems、FavoriteItems、WatchHistory、Sessions/Playing、Progress、Stopped账号服务:状态与上报落库、续期与并发计数
文件下载Items/{id}/Download播放节点本地出流,需下载权限(管理员或开了「允许下载」的用户)

流端点只认播放节点

媒体服务上的 stream.* / original.* 路径刻意返回 404:出流必须经播放节点, 否则等于绕过用户级来源访问控制与流量计量。排查「客户端能列库但放不了」时先确认地址指向的是 play-agent 入口。

协议面上的鉴权与准入 ​

  • 凭据形态:AuthenticateByName(用户名 + 密码,即系统账号)换发会话令牌; X-Emby-Authorization / X-Emby-Token / X-MediaBrowser-Token 头与 URL api_key 都被接受, Jellyfin 习惯的无前缀 URL 同样可达。
  • 直链加速参数带 exp 与 HMAC 签名(默认有效期 6 小时);未带签名的请求回退按会话令牌校验—— 不破坏 Infuse 这类「直连播放」模式的客户端。
  • 客户端 User-Agent 白/黑名单在登录之前就生效:未准入的客户端连 AuthenticateByName 都会 403。 匹配方式是子串包含而非正则(规则见访问管控)。 图片与字幕的 GET 请求豁免这一层,不占节点授权与配额。
  • 用户须有对应节点授权;流量配额耗尽时新请求被拒、播放中每 30 秒复核一次字节账、耗尽即掐流, 且耗尽的入口不会出现在门户下发列表里。

三条热路径的加速与缓存 ​

① 浏览与搜索:Redis 结果缓存 ​

媒体服务对协议查询面挂了结果缓存:库列表、浏览与搜索结果、条目详情、演职员、虚拟库浏览。 策略是永久缓存 + 主动失效——不按过期时间赌命中率,库同步、刮削、元数据覆盖改动哪些条目, 就精确清掉哪些缓存键,客户端下次查询立即看到新数据。

总开关是环境变量 YIYI_CACHE_ENABLED(默认开);关掉后每次查询都直打数据库,仅排障用。

② 海报墙:节点本地图片缓存 ​

图片端点先查节点磁盘缓存,命中直接返回——海报墙是并发最密集的接口族,逐张回源会把上游打爆。 响应头 X-Image-Cache: HIT / MISS 可以直接在开发者工具里验证命中。

细节上都为「滚动画廊」场景调过:未命中时异步落盘、不阻塞响应; 客户端滚动中途取消请求,节点仍会把回源结果补进缓存,下一屏再滚到就是命中。 上游图片按请求宽度映射到 TMDB 的现成尺寸桶,节点不做缩放。 容量、目录、保留期在后台播放设置与缓存的「图片缓存」Tab 按节点配置 (默认上限 500 MB / 保留 7 天),没有按条目失效——改了海报就清空该节点缓存。 用户头像固定返回站点 Logo,跟白标品牌设置走。

③ 启播与上游:字节缓存 + 直链复用 ​

  • VFS 智能启播缓存:目标是让更多片子更快出画面,不是缓存整片。节点用 ffprobe 摸清 容器元数据(moov、索引)的真实位置,只落盘「基础头部 + 必要索引 + 少量开场字节」, 单个响应内混合「本地缓存段 + 上游有界直传」并保持原文件偏移。启播回放验证成功即停。 磁盘写满自动降级直传,不中断播放。机制详见核心概念与播放设置与缓存。
  • 签名直链复用:一部 4 GB 影片要发数百个分片请求,逐片向云盘换直链必触发风控。 节点按「网盘 + 条目」缓存已签发的直链(TTL 从链接自带的过期参数推算), 同一直链的并发请求合并成一次远端调用;401/403 才重取一次;令牌失效类错误做 5 分钟 负向缓存,避免反复打云盘 API。
  • 上游选路:Google Drive 走账号池分流 + 每 60 秒的 CDN IP 测速优选(节点内优选, 不是节点间调度);115 直链由 Open API 现场签发。直链级适配目前只覆盖这两类网盘, 未来会兼容更多;本地磁盘直读,其余来源经存储节点代理字节流,不走换链逻辑。
  • 入口列表缓存:门户「客户端配置」的入口清单由账号服务经 Redis 缓存并按用户授权 过滤后下发,多用户并发取地址不打到数据库。

明确不做什么 ​

边界实际行为
转码 / 转封装 / 真 HLS都没有。PlaybackInfo 明确 SupportsTranscoding=false;下发给客户端的 m3u8 是「单段清单」,内容就是那条签名直链,没有切片与码率阶梯。客户端「播放质量」档位(MaxStreamingBitrate)不影响输出字节流
服务端 seek / 轨道切换StartTimeTicks、AudioStreamIndex、SubtitleStreamIndex 参数收下即忽略;拖动与换轨全靠客户端自己对同一路流处理
字幕格式转换没有 SRT↔VTT/ASS 转换,请求后缀只决定响应 Content-Type,正文原样下发
Jellyfin / Plex 协议无独立实现:兼容面只有 Emby,协议开关首位不是 emby 时整个协议面 503;Jellyfin 客户端可按 Emby URL 形状接入
实时推送与部分标准端点无 WebSocket、无 Users/Me、无登出/令牌吊销端点、无 DLNA / Sync / Devices / 直播电视;收藏与历史靠轮询刷新。会话令牌签出后长期有效
缓存命中率看板页面没有这个指标;验证靠 X-Image-Cache 响应头与「查看缓存内容」的字节区间条
节点间自动调度没有按负载选节点的逻辑;多入口由用户手动配置与切换
Trickplay / 预告片缩略图雪碧恒空、本地预告片恒空,靠进度条精确预览的客户端体验会退化

相关文档 ​

自托管媒体管理系统(单机版 / 分布式版) · 想先体验或有问题,加 Telegram 群:t.me/yiyi_media_group