bpking1 / embyExternalUrl

some emby/jellyfin scripts
MIT License
698 stars 126 forks source link

有没有可能搞一个青春版 #214

Closed intheshell2077 closed 3 months ago

intheshell2077 commented 3 months ago

冒昧问一句,未来可不可以搞一个仅包含实现直链相关功能的独立的配置哦,类似青春版。其实原始需求就是通过njs+alist的使用,让Plex/Emby支持直链播放。这怎么还越搞越复杂了呢。譬如我现在遇到的难题是:我已经有了自己的nginx配置,我不想要其他的配置,只想单独把直链这部分实现搞到我自己的配置中,这就变得难上加难了...

感谢你的分享。

chen3861229 commented 3 months ago

这个其实分支开起来不难,但是维护起来比较麻烦,而且稍微有些没必要,其实相较于 bpking1 大佬的最初版本,只是加了些细节上的修复,总体变化不算太大,全部默认配置的情况下也还是走直链的,不会有转码的情况,后边加的所有配置基本都是可选项,根据你的需求,其实只用关注这两个配置文件就行了,和之前的是一样的,其余的复制过去不用改它们

emby2Alist\nginx\conf.d\constant.js
emby2Alist\nginx\conf.d\config\constant-mount.js
intheshell2077 commented 3 months ago

我尝试把这个融合到我的nginx配置中,出现了一些报错,集中在这里:plex2Pan.plexApiHandler,请问这个plexApiHandler是做啥的,我看大部分请求都被这个拦截了

chen3861229 commented 3 months ago

1.plexApiHandler 这个是缓存 partInfo 树对象的媒体文件路径信息的,plex 的媒体 URL 在 part 对象的 key 上,不包含媒体的路径信息,因为是树的叶子节点,当然 plex 官方也不可能提供直接的查询接口 2.plex 部分客户端用到了 xml 格式报文,所以 plex.js 最上方引入了 xml 包,njs 版本需要 >= 0.7.10 https://nginx.org/en/docs/njs/reference.html#xml

intheshell2077 commented 3 months ago

页面都出不来了,nginx log一直出现如下错误:

2024/06/18 11:05:59 [error] 38#38: *16 too big subrequest response: 72481 while sending to client, client: 172.71.210.16, server: plex.org, request: "GET /library/sections/14/all?type=2&sort=episode.addedAt%3Adesc&includeCollections=1&includeExternalMedia=1&includeAdvanced=1&includeMeta=1&X-Plex-Product=Plex%20Web&X-Plex-Version=4.129.1&X-Plex-Client-Identifier=u6m0a4og7ckrxx15vrk0nq6p&X-Plex-Platform=Safari&X-Plex-Platform-Version=16.6&X-Plex-Features=external-media%2Cindirect-media%2Chub-style-list&X-Plex-Model=bundled&X-Plex-Device=OSX&X-Plex-Device-Name=Safari&X-Plex-Device-Screen-Resolution=1440x795%2C1440x900&X-Plex-Container-Start=0&X-Plex-Container-Size=50&X-Plex-Token=uuyRrQZTyovwDfhULsG3&X-Plex-Provider-Version=6.5&X-Plex-Text-Format=plain&X-Plex-Drm=fairplay&X-Plex-Language=en HTTP/2.0", subrequest: "/library/sections/14/all", upstream: "http://127.0.0.1:32400/library/sections/14/all?type=2&sort=episode.addedAt%3Adesc&includeCollections=1&includeExternalMedia=1&includeAdvanced=1&includeMeta=1&X-Plex-Product=Plex%20Web&X-Plex-Version=4.129.1&X-Plex-Client-Identifier=u6m0a4og7ckrxx15vrk0nq6p&X-Plex-Platform=Safari&X-Plex-Platform-Version=16.6&X-Plex-Features=external-media%2Cindirect-media%2Chub-style-list&X-Plex-Model=bundled&X-Plex-Device=OSX&X-Plex-Device-Name=Safari&X-Plex-Device-Screen-Resolution=1440x795%2C1440x900&X-Plex-Container-Start=0&X-Plex-Container-Size=50&X-Plex-Token=xxx&X-Plex-Provider-Version=6.5&X-Plex-Text-Format=plain&X-Plex-Drm=fairplay&X-Plex-Language=en", host: "plex.org", referrer: "https://plex.org/web/index.html"

2024/06/18 11:05:59 [error] 38#38: 16 pending events while closing request, client: 172.71.210.16, server: 0.0.0.0:4432024/06/18 11:05:59 [error] 38#38: 16 too big subrequest response: 72481 while sending to client, client: 172.71.210.16, server: plex.org, request: "GET /library/sections/14/all?type=2&sort=episode.addedAt%3Adesc&includeCollections=1&includeExternalMedia=1&includeAdvanced=1&includeMeta=1&X-Plex-Product=Plex%20Web&X-Plex-Version=4.129.1&X-Plex-Client-Identifier=u6m0a4og7ckrxx15vrk0nq6p&X-Plex-Platform=Safari&X-Plex-Platform-Version=16.6&X-Plex-Features=external-media%2Cindirect-media%2Chub-style-list&X-Plex-Model=bundled&X-Plex-Device=OSX&X-Plex-Device-Name=Safari&X-Plex-Device-Screen-Resolution=1440x795%2C1440x900&X-Plex-Container-Start=0&X-Plex-Container-Size=50&X-Plex-Token=uuyRrQZTyovwDfhULsG3&X-Plex-Provider-Version=6.5&X-Plex-Text-Format=plain&X-Plex-Drm=fairplay&X-Plex-Language=en HTTP/2.0", subrequest: "/library/sections/14/all", upstream: "http://127.0.0.1:32400/library/sections/14/all?type=2&sort=episode.addedAt%3Adesc&includeCollections=1&includeExternalMedia=1&includeAdvanced=1&includeMeta=1&X-Plex-Product=Plex%20Web&X-Plex-Version=4.129.1&X-Plex-Client-Identifier=u6m0a4og7ckrxx15vrk0nq6p&X-Plex-Platform=Safari&X-Plex-Platform-Version=16.6&X-Plex-Features=external-media%2Cindirect-media%2Chub-style-list&X-Plex-Model=bundled&X-Plex-Device=OSX&X-Plex-Device-Name=Safari&X-Plex-Device-Screen-Resolution=1440x795%2C1440x900&X-Plex-Container-Start=0&X-Plex-Container-Size=50&X-Plex-Token=xxx&X-Plex-Provider-Version=6.5&X-Plex-Text-Format=plain&X-Plex-Drm=fairplay&X-Plex-Language=en", host: "plex.org", referrer: "https://plex.org/web/index.html"

2024/06/18 11:05:59 [error] 38#38: *16 pending events while closing request, client: 172.71.210.16, server: 0.0.0.0:443

chen3861229 commented 3 months ago

2024/06/18 11:05:59 [error] 38#38: *16 too big subrequest response: 72481 while sending to client, client: 172.71.210.16, server: plex.org, request: "GET /library/sections/14/all?

这行日志已经很清晰了,确认下 plex.conf 中 subrequest_output_buffer_size 这个参数的大小,nginx 的默认值是很小的,只有 4KB / 8KB image

intheshell2077 commented 3 months ago

修改了这个,页面可以载入了,但是无法播放。log里面频繁见到如下错误:

2024/06/21 11:44:27 [warn] 40#40: 557 js: === plexApiHandler: /library/metadata/591919, the NJS VM is destroyed === 2024/06/21 11:44:27 [warn] 40#40: 557 js: plexApiHandler subrequest failed, status: 401/404 2024/06/21 11:44:27 [warn] 40#40: 557 js: use original link 2024/06/21 11:44:27 [warn] 40#40: 557 js: Property "path" not found in object,will ignore 2024/06/21 11:44:27 [warn] 40#40: 557 js: Property "mediaIndex" not found in object,will ignore 2024/06/21 11:44:27 [warn] 40#40: 557 js: Property "partIndex" not found in object,will ignore 2024/06/21 11:44:27 [error] 40#40: *557 js: error: internalRedirectAfter: TypeError: cannot get property "get" of undefined

2024/06/21 11:37:14 [error] 38#38: *490 js exception: Error: unhandled promise rejection: TypeError: cannot get property "get" of undefined at redirect2Pan (/etc/nginx/njs-script/plex.js:35)

plex.js 35行这里是这句:cachedLink = ngx.shared[routeDictKey].get(cacheKey);

另外,我其实不太理解为什么要发起那么多的子请求,这样真的不会影响nginx的性能和效率吗,还有,你之前说的,part对象,/metadata/这个请求里面,不是可以直接拿到具体的视频挂载路径么。

intheshell2077 commented 3 months ago

顺便说一下我的使用方式,不确定是否使用正确,引用如下:

njs文件 constant-all.js (只修改这里面的参数) events.js periodics.js util.js plex.js

conf文件 plex.conf 我将注释中PlexMediaServer从Start到End之间的配置,加到我自己的conf中,同时增加了subrequest_output_buffer_size设置

nginx使用官方nginx:alpine镜像最新版,njs版本应该也是最新的

chen3861229 commented 3 months ago

plex.js 35行这里是这句:cachedLink = ngx.shared[routeDictKey].get(cacheKey);

1.这里还需要内存缓存的配置块,plex 依赖于此

image

另外,我其实不太理解为什么要发起那么多的子请求,这样真的不会影响nginx的性能和效率吗

2.不会影响的,因为子请求是 NJS 中自定义实现反代功能的工具,客户端请求只到达了 nginx , 不发子请求是不会从 nginx 到达源服务的,也就是请求从客户端出发只走了一遍,很多人对这个过程觉得是多走了一遍,是不对的,至于为什么需要这样处理,就是下面的了

还有,你之前说的,part对象,/metadata/这个请求里面,不是可以直接拿到具体的视频挂载路径么。

3.大量播放链接走的直接是 part 的请求,这个单独的 URL 中是没有任何能获取文件路径的办法的,location ~* /library/parts/(\d+)/(\d+)/file ,/metadata/ 这个是客户端单独的请求,多线程请求下都是分离的,无法关联使用,/metadata/ 的 media 和 parts 这两个对象是一对多的树结构,plex 没有提供直接查询 part 这个子节点信息的接口且 /library/parts/(\d+)/(\d+)/file 链接中做了类似于混淆的处理,没有任何实际含义,两串数字只是文件的修改时间戳,要么查询 sql lite 数据库,要么就是目前的处理 /metadata/ 之类的接口以缓存此结构中树的子节点 part 的文件路径信息,你提到的这个前提是双方能有一个关联信息,缓存 part 信息就是来实现这个功能的,只是为了提升效率,缓存中并没有维护 metadata 和 parts 的关联关系,表现形式为只缓存了 part 的路径信息,因为此脚本只关注这个信息

4.NJS 的文件用得没问题,但是 plex.conf 文件中应该缺失了很大一部分配置,不要被注释中PlexMediaServer从Start到End之间这个影响到了,这段单纯只是标记和 emby.conf 的 location 之间的不同之处,建议先全量正常使用了,再考虑自定义精简,location / 和 location @root 也是必须要的,整段 conf 中唯一能去掉不影响的应该只有 gzip on 那段了