From 8136e6ecb17ef375115a2bab2be88b5eb0b53d4b Mon Sep 17 00:00:00 2001 From: truewhile <62226914+truewhile@users.noreply.github.com> Date: Mon, 28 Sep 2026 22:51:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(emby):=20=E7=94=B5=E5=BD=B1=E6=9D=A1?= =?UTF-8?q?=E7=9B=AE=E4=B8=8D=E4=B8=8B=E5=8F=91=E7=A9=BA=E7=9A=84=20Season?= =?UTF-8?q?Id/SeriesId=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=B0=8F=E5=B9=BB?= =?UTF-8?q?=E5=BD=B1=E8=A7=86=E8=B5=B7=E6=92=AD=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 小幻影视(RodelPlayer)2.2610 会把电影条目的 SeasonId 空串原样传进自己的 播放准备逻辑并抛 ArgumentException(Parameter 'seasonId'),客户端日志里 表现为 failedStage=PreparationFailed、playback generation null,也就是 点播放立刻「播放失败」;剧集条目的 SeasonId 非空,所以同一台设备放剧集正常。 Emby/Jellyfin 对「不适用」的字段是直接不下发(JSON 里没有该键)而不是下发空串。 这里对非剧集条目省略 SeasonId/SeriesId/SeasonName/SeriesName(顺带去掉电影被 标成「特别篇」的 SeasonName),剧集则保留真实季/剧信息、只清空值。 同时回退上一版针对 115 直链 UA 绑定的同源一跳改动:客户端日志显示该客户端的 播放器层与 API 层 UA 是一致的(剧集走服务端换链后的一跳直连可以正常解码播放), 不需要为此牺牲起播速度。 --- internal/handler/emby_playback.go | 25 ---- .../handler/emby_video_stream_resolve_test.go | 138 ------------------ .../emby_item_payload_empty_ids_test.go | 92 ++++++++++++ internal/service/emby_items_detail.go | 25 ++++ .../service/stream_direct_redirect_test.go | 37 ----- internal/service/stream_file.go | 35 ----- 6 files changed, 117 insertions(+), 235 deletions(-) delete mode 100644 internal/handler/emby_video_stream_resolve_test.go create mode 100644 internal/service/emby_item_payload_empty_ids_test.go diff --git a/internal/handler/emby_playback.go b/internal/handler/emby_playback.go index b49446b..0450f7a 100644 --- a/internal/handler/emby_playback.go +++ b/internal/handler/emby_playback.go @@ -348,12 +348,6 @@ func embyVideoStreamHandler(svc *service.Container, cloudMode string) gin.Handle // 此前这里把所有错误一律吞成 404:云盘 Cookie 过期、直链解析失败、 // STRM 播放被关闭……在第三方播放器上全部表现为「404 不存在」, // 无法排查。现在区分:行不存在→404;云盘播放不可用/上游故障→502+原因。 - // - // 网盘直链与换取时的 UA 严格绑定,而 Emby 客户端的 API 层与播放器层 UA - // 不保证相同(浏览器一定相同),所以只有浏览器客户端允许服务端短路换链。 - if !isBrowserLikeUserAgent(c.GetHeader("User-Agent")) { - c.Request = c.Request.WithContext(service.WithClientSideSTRMResolve(c.Request.Context())) - } err = svc.Stream.ServeFileWithCloudMode(c.Writer, c.Request, c.Param("id"), cloudMode) switch { case err == nil: @@ -393,25 +387,6 @@ func embyPlaybackRedirectToken(c *gin.Context, svc *service.Container) string { return token } -// isBrowserLikeUserAgent 判断请求是否来自浏览器(含 WebView / Electron 客户端)。 -// -// 只有浏览器能保证「API 请求」与「