bpking1 / embyExternalUrl

some emby/jellyfin scripts
MIT License
778 stars 134 forks source link

[Question] 本地文件+Alist/OneDrive+Emby直链后内网提示没有兼容的流 #107

Closed sgpublic closed 6 months ago

sgpublic commented 7 months ago

先行感谢大佬们一直以来的努力。

我的情况是,非 rclone 挂载,而是本地文件,然后同步到 OneDrive E5,希望外网通过 Alist 直链播放,内网照旧。

emby 用 docker 部署,是将几个文件夹直接挂载到根目录,比如番剧挂载到容器内 /mnt/media/Bangumi,对应到 Alist 就是 /public/emby-media/Bangumi

然后我外网是通过 frp 穿进来的,用了 proxy protocol v2,所以 nginx 是自己配了(但也是大部分直接复制):

media.conf ``` # 此文件只需要更改listen, SSL, cache, periodics相关配置 # Load the njs script js_path /etc/nginx/modules.d/embyExternalUrl/emby2Alist/nginx/conf.d/; js_import config from constant.js; js_import emby2Pan from emby.js; js_import embyLive from emby-live.js; js_import periodics from common/periodics.js; js_import transcode from emby-transcode.js; # Memory Cache, workers shared values, since njs 0.8.0 js_shared_dict_zone zone=transcodeDict:5M timeout=4h evict; js_shared_dict_zone zone=redirectDict:10M timeout=15m evict; # FileSystem Cache, images, subtitles proxy_cache_path /var/cache/nginx/emby/images levels=1:2 keys_zone=emby_images:100m max_size=10g inactive=30d use_temp_path=off; proxy_cache_path /var/cache/nginx/emby/subtitles levels=1:2 keys_zone=emby_subtitles:10m max_size=1g inactive=30d use_temp_path=off; server { server_name xxx; listen 80; listen [::]:80; listen 19080 proxy_protocol; listen [::]:19080 proxy_protocol; # enforce https return 301 https://$server_name$request_uri; } upstream transcode_group { least_conn; server 127.0.0.1:8096; } server { server_name xxx; listen 443 ssl; listen [::]:443 ssl; listen 19443 ssl proxy_protocol; listen [::]:19443 ssl proxy_protocol; ssl_certificate xxx; ssl_certificate_key xxx; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; set_real_ip_from 10.51.0.0/16; js_set $emby config.getEmbyHost; #emby/jellyfin address js_set $transcodeBalanceEnable config.getTranscodeBalanceEnable; js_set $transcodeBalanceType config.getTranscodeBalanceType; js_set $imageCachePolicy config.getImageCachePolicy; resolver 192.168.6.1; js_fetch_verify off; client_max_body_size 20M; subrequest_output_buffer_size 200k; add_header 'Referrer-Policy' 'no-referrer'; # internal redirect location ~ ^(.*)/proxy(/.*)$ { internal; # internal use only gunzip on; # Jellyfin/Plex has gzip,need this,Emby no gzip but compatible proxy_set_header Accept-Encoding ""; # subrequest need this client_body_in_file_only clean; rewrite ^(.*)/proxy(/.*)$ $1$2 break; # include /etc/nginx/common.d/listen_location_with_no_version.conf; proxy_pass $emby$request_uri; # Emby/Plex need $request_uri,Jellyfin not need but compatible proxy_pass_request_body on; proxy_pass_request_headers on; add_header X-Proxy-Success true; # for debug } # Proxy PlaybackInfo location ~* /Items/(.*)/PlaybackInfo { client_body_in_file_only clean; set $flag ""; if ($transcodeBalanceEnable != true) { set $flag "${flag}1"; } # if ($args ~* "IsPlayback=true") { # set $flag "${flag}1"; # } if ($flag = "1") { js_content emby2Pan.transferPlaybackInfo; add_header X-Modify-Success true; # for debug break; } # include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } # Proxy Users Items Info location ~* /Users/(.*)/Items$ { proxy_set_header Accept-Encoding ""; set $flag searchSuggest; if ($arg_SortBy ~* Random ) { js_content emby2Pan.itemsFilter; add_header X-Modify-Success true; # for debug break; } # include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } # Proxy Items Similar location ~* /Items/(.*)/Similar$ { proxy_set_header Accept-Encoding ""; set $flag itemSimilar; if ($args !~* GroupProgramsBySeries ) { js_content emby2Pan.itemsFilter; add_header X-Modify-Success true; # for debug break; } # include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } # Proxy SystemInfo location ~* /system/info$ { proxy_set_header Accept-Encoding ""; js_content emby2Pan.systemInfoHandler; add_header X-Modify-Success true; # for debug } # Redirect the stream to njs location ~* /videos/(.*)/(stream|original) { # limit_req zone=one; # some packaged 3rd party players called intent has bug, concurrent 2 req, disable one of them # if ($http_user_agent ~* "dandanplay/android") { # return 200; # } # Cache alist direct link add_header Cache-Control max-age=3600; rewrite ^(.*)/stream/(.*)$ $1/$2 break; # Remove modified path "stream/" js_content emby2Pan.redirect2Pan; } # Redirect the live to njs location ~* /videos/(.*)/live { js_content embyLive.directLive; } location ~* /videos/(.*)/master { if ($args ~* "skipDirect=1") { # include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; break; } set $flag ""; if ($transcodeBalanceEnable = true) { set $flag "${flag}1"; } if ($transcodeBalanceType = nginx) { set $flag "${flag}1"; } if ($flag = "11") { add_header X-Upstream-Addr $upstream_addr; # for debug proxy_pass http://transcode_group; break; } if ($flag = "1") { js_content transcode.transcodeBalance; break; } js_content embyLive.directLive; } # Stops an active encoding location ~* /Videos/ActiveEncodings { if ($transcodeBalanceEnable = true) { js_content transcode.syncDelete; break; } # include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } # Sessions Playing Stat location ~* /Sessions/Playing { if ($transcodeBalanceEnable = true) { js_content transcode.syncPlayState; break; } # include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } # Redirect Audio the stream to njs location ~* /Audio/(.*)/universal { # Cache alist direct link add_header Cache-Control max-age=3600; js_content emby2Pan.redirect2Pan; } # for webClient download ,android is SyncService api location ~* /Items/([^/]+)/Download { js_content emby2Pan.redirect2Pan; } # Emby for android download ,this is SyncService api only Emby location ~* /Sync/JobItems/(.*)/File { # Cache alist direct link add_header Cache-Control max-age=3600; js_content emby2Pan.redirect2Pan; } # Cache the images location ~ /Items/(.*)/Images { set $tmp_proxy_cache_key $uri; set $tmp_remove_args false; if ($imageCachePolicy = 1) { set $tmp_proxy_cache_key $request_uri; } set $tmp_args &${args}; if ($tmp_args ~* ^(.*)(&maxHeight=\w*)(.*)$) { set $tmp_args $1$3; } if ($tmp_args ~* ^(.*)(&maxWidth=\w*)(.*)$) { set $tmp_args $1$3; } if ($tmp_args ~* ^(.*)(&quality=\w*)(.*)$) { set $tmp_args $1$3; } if ($tmp_args ~* ^&(.*)$) { set $tmp_args $1; } if ($imageCachePolicy = 2) { set $args $tmp_args; set $tmp_remove_args true; # for debug } # include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; proxy_cache emby_images; proxy_cache_revalidate on; proxy_cache_lock_timeout 10s; proxy_cache_lock on; proxy_cache_valid 200 30d; proxy_cache_key $tmp_proxy_cache_key; add_header X-Cache-Key $tmp_proxy_cache_key; # for debug add_header X-Remove-Args $tmp_remove_args; # for debug add_header X-Modifly-Args $args; # for debug add_header X-Cache-Status $upstream_cache_status; # This is only to check if cache is working } ## Disables access to swagger/openapi interface location ~* /(swagger|openapi) { return 404; } location ~ / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $REAL_REMOTE_ADDR; proxy_set_header X-Forwarded-For $REAL_X_FORWARDED_FOR; proxy_set_header X-NginX-Proxy true; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_redirect off; proxy_pass $emby; } } ```

配置文件如下:

constrant.js ``` // 全量配置,媒体库混合,本地文件 + CD2/rclone挂载的alist文件 + strm文件 // export constant allocation // 必填项,根据实际情况修改下面的设置 // 这里默认emby/jellyfin的地址是宿主机,要注意iptables给容器放行端口 const embyHost = "http://127.0.0.1:8096"; // rclone 的挂载目录, 例如将od, gd挂载到/mnt目录下: /mnt/onedrive /mnt/gd ,那么这里就填写 /mnt // 通常配置一个远程挂载根路径就够了,默认非此路径开头文件将转给原始emby处理,不用重复填写至disableRedirectRule // 如果没有挂载,全部使用strm文件,此项填[""],必须要是数组 const embyMountPath = ["/mnt/media"]; // const embyMountPath = [""]; // emby/jellyfin api key, 在emby/jellyfin后台设置 const embyApiKey = "xxx"; // 访问宿主机上5244端口的alist地址, 要注意iptables给容器放行端口 const alistAddr = "http://127.0.0.1:5244"; // alist token, 在alist后台查看 const alistToken = "alist-xxx"; // 选填项,用不到保持默认即可 // alist公网地址, 用于需要alist server代理流量的情况, 按需填写 const alistPublicAddr = "https://example.com"; // 局域网ip头 const lanIpHead = ["172.", "10.", "192.", "[fd00:"]; // 禁用直链的规则,将转给原始媒体服务器处理,字幕和图片没有走直链,不用添加 // 参数1: 匹配类型或来源(字符串参数类型) "0": 文件路径(Item.Path) // 参数2: 0: startsWith(str), 1: endsWith(str), 2: includes(str), 3: match(/ain/g) // 参数3: 匹配目标 // 参数4: 是否处理alist响应链接 const disableRedirectRule = [ // ["0", 0, "/mnt/sda1"], // ["0", 1, ".mp3"], // ["0", 2, "Google"], // ["0", 2, "/NAS/", true], // 例如使用alias聚合了nas本地文件,可能会存在卡顿或花屏 // ["0", 3, /private/ig], // docker注意必须为host模式,不然此变量全部为内网ip,判断无效,nginx内置变量不带$,客户端地址($remote_addr) ["r.variables.remote_addr", 0, lanIpHead], // ["r.headersIn.User-Agent", 2, "IE"], // 请求头参数,客户端UA // ["r.args.X-Emby-Device-Id", 0, "d4f30461-ec5c-488d-b04a-783e6f419eb1"], // 链接入参,设备id // ["r.args.X-Emby-Device-Name", 0, "Microsoft Edge Windows"], // 链接入参,设备名称 // ["r.args.X-Emby-Client", 0, "Emby Web"], // 链接入参,客户端类型 // ["r.args.UserId", 0, "ac0d220d548f43bbb73cf9b44b2ddf0e"], // 链接入参,用户id ]; // 路径映射,会在xxxMountPath之后从上到下依次全部替换一遍,不要有重叠 // 参数1: 0: 默认做字符串替换, 1: 前插, 2: 尾插 // 参数2: 0: 默认只处理/开头的路径且不为strm, 1: 只处理strm内部为/开头的相对路径, 2: 只处理strm内部为远程链接的 // 参数3: 来源, 参数4: 目标 const embyPathMapping = [ // [0, 0, "/mnt/aliyun-01", "/mnt/aliyun-02"], // [0, 2, "http:", "https:"], // [0, 2, ":5244", "/alist"], // [0, 0, "D:", "F:"], // [0, 0, /blue/g, "red"], // 此处正则不要加引号 [1, 0, `${alistPublicAddr}/d/public/emby-media`], // [2, 2, "?xxx"], ]; // 指定是否转发由njs获取strm重定向后直链地址的规则,例如strm内部为局域网ip或链接或需要请求头验证 // 参数1: 0: startsWith(str), 1: endsWith(str), 2: includes(str), 3: match(/ain/g) // 参数2: 匹配目标,对象为xxxPathMapping映射后的strm内部链接 // 参数3: 请求验证类型,已为直链的不需要此参数,例如.../d const redirectStrmLastLinkRule = [ // [0, lanIpHead.map(s => "http://" + s)], // [0, alistAddr], // [0, "http:"], // // 参数4: 已为直链的不需要此参数, 参数暂无作用, sign属于额外验证 // [0, "http://otheralist1.com", "FixedToken", alistToken], // // arg4: 已为直链的不需要此参数,额外指定调用登录接口的api地址, 参数暂无作用, sign属于额外验证 // [0, "http://otheralist2.com", "TempToken", `read:123456`, `http://otheralist2.com:5244/api/auth/login`], ]; // 指定客户端自己请求并获取alist直链的规则,代码优先级在redirectStrmLastLinkRule之后 // 特殊情况使用,则此处必须使用域名且公网畅通,用不着请保持默认 // 参数1: 0: startsWith(str), 1: endsWith(str), 2: includes(str), 3: match(/ain/g) // 参数2: 匹配目标,对象为Alist接口返回的链接raw_url // 参数3: 指定转发给客户端的alist的host前缀 const cilentSelfAlistRule = [ // [2, "xxx", alistPublicAddr], ]; // !!!实验功能,转码负载均衡,默认false,将按之前逻辑禁止转码处理并移除转码选项参数,与emby配置无关 // 主库和所有从库给用户开启[播放-如有必要,在媒体播放期间允许视频转码]+[倒数7行-允许媒体转换] // type: "nginx", nginx负载均衡,好处是使用简单且内置均衡参数选择,缺点是流量全部经过此服务器, // 且使用条件很苛刻,转码服务组中的媒体id需要和主媒体库中id一致,自行寻找实现主从同步,完全同步后,ApiKey也是一致的 // type: "distributed-media-server", 分布式媒体服务负载均衡(暂未实现均衡),优先利用302真正实现流量的LB,且灵活, // 不区分主从,当前访问服务即为主库,可emby/jellyfin混搭,挂载路径可以不一致,但要求库中的标题和语种一致且原始文件名一致 const transcodeBalanceConfig = { enable: false, type: "distributed-media-server", // 可选值, ["nginx", "distributed-media-server"] maxNum: 3, // 单机最大转码数量,有助于加速轮询, 参数暂无作用,接口无法查询转码情况,忽略此参数 server: [ { type: "emby", host: "http://172.17.0.1:8096", apiKey: "f839390f50a648fd92108bc11ca6730a", }, { type: "jellyfin", host: "http://172.17.0.2:8097", apiKey: "f839390f50a648fd92108bc11ca6730a", }, // plex和weight参数暂未实现,很难 // { // type: "plex", // host: "http://172.17.0.2:32400", // apiKey: "f839390f50a648fd92108bc11ca6730a", // }, ] }; // 图片缓存策略,包括主页、详情页、图片库的原图,路由器nginx请手动调小conf中proxy_cache_path的max_size // 0: 不同尺寸设备共用一份缓存,先访问先缓存,空间占用最小但存在小屏先缓存大屏看的图片模糊问题 // 1: 不同尺寸设备分开缓存,空间占用适中,命中率低下,但契合emby的图片缩放处理 // 2: 不同尺寸设备共用一份缓存,空间占用最大,移除emby的缩放参数,直接原图高清显示 const imageCachePolicy = 1; // 对接emby通知管理员设置,目前只发送是否直链成功,依赖emby/jellyfin的webhook配置并勾选外部通知 const embyNotificationsAdmin = { enable: true, includeUrl: false, // 链接太长,默认关闭 name: "【emby2Alist】", }; // 对接emby设备控制推送通知消息,目前只发送是否直链成功,此处为统一开关,范围为所有的客户端,通知目标只为当前播放的设备 const embyRedirectSendMessage = { enable: true, header: "【emby2Alist】", timeoutMs: 0, // 消息通知弹窗持续毫秒值 }; // 按路径匹配规则隐藏部分接口返回的items // 参数1: 0: startsWith(str), 1: endsWith(str), 2: includes(str), 3: match(/ain/g) // 参数2: 匹配目标,对象为Item.Path // 参数3: 默认同时隐藏[搜索建议(不会过滤搜索接口)]和[更多类似(若当前浏览项目位于规则中,将跳过隐藏)]接口 // 0: 默认, 1: 只隐藏[搜索建议]接口, 2: 只隐藏[更多类似]接口 const itemHiddenRule = [ // [0, "/mnt/sda1"], // [1, ".mp3", 1], // [2, "Google", 2], // [3, /private/ig], ]; // for js_set function getEmbyHost(r) { return embyHost; } function getTranscodeBalanceEnable(r) { return transcodeBalanceConfig.enable; } function getTranscodeBalanceType(r) { return transcodeBalanceConfig.type; } function getImageCachePolicy(r) { return imageCachePolicy; } export default { embyHost, embyMountPath, embyApiKey, disableRedirectRule, alistAddr, alistToken, alistPublicAddr, cilentSelfAlistRule, embyPathMapping, redirectStrmLastLinkRule, embyNotificationsAdmin, embyRedirectSendMessage, itemHiddenRule, transcodeBalanceConfig, getEmbyHost, getTranscodeBalanceEnable, getTranscodeBalanceType, getImageCachePolicy, } ```

然后 nginx 日志如下:

error.log ``` 2024/04/18 17:59:02 [notice] 277#277: *3688 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000073, client: 192.168.6.163, server: xxx.example.com, request: "POST /emby/Items/11040/PlaybackInfo?UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&StartTimeTicks=0&IsPlayback=true&AutoOpenLiveStream=true&MaxStreamingBitrate=160000000&X-Emby-Client=Emby+Web&X-Emby-Device-Name=Microsoft+Edge+Windows&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client-Version=4.9.0.11&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&X-Emby-Language=zh-cn&reqformat=json HTTP/1.1", host: "xxx.example.com" 2024/04/18 17:59:02 [warn] 277#277: *3688 js: playbackinfo proxy uri: /proxy/emby/Items/11040/PlaybackInfo 2024/04/18 17:59:02 [warn] 277#277: *3688 js: playbackinfo proxy query string: IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AutoOpenLiveStream=true&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&X-Emby-Device-Name=Microsoft Edge Windows&X-Emby-Language=zh-cn 2024/04/18 17:59:02 [warn] 277#277: *3688 js: origin playbackinfo: {"MediaSources":[{"Protocol":"File","Id":"74859721e1d4f9d0ded5192d3d5ca4c2","Path":"/Bangumi/家里蹲吸血姬的郁闷 (2023)/Season 1/家里蹲吸血姬的郁闷 - S01E06 - 怪人云集的圆桌会议.mkv","Type":"Default","Container":"mkv","Size":258739171,"Name":"家里蹲吸血姬的郁闷 - S01E06 - 怪人云集的圆桌会议","IsRemote":false,"HasMixedProtocols":false,"RunTimeTicks":14419900000,"SupportsTranscoding":true,"SupportsDirectStream":true,"SupportsDirectPlay":true,"IsInfiniteStream":false,"RequiresOpening":false,"RequiresClosing":false,"RequiresLooping":false,"SupportsProbing":false,"MediaStreams":[{"Codec":"h264","Language":"jpn","ColorTransfer":"bt709","ColorPrimaries":"bt709","ColorSpace":"bt709","TimeBase":"1/1000","Title":"Japanese","VideoRange":"SDR","DisplayTitle":"1080p H264","DisplayLanguage":"Japanese","NalLengthSize":"4","IsInterlaced":false,"BitRate":1435456,"BitDepth":8,"RefFrames":1,"IsDefault":true,"IsForced":false,"IsHearingImpaired":false,"Height":1080,"Width":1920,"AverageFrameRate":23.976025,"RealFrameRate":23.976025,"Profile":"High","Type":"Video","AspectRatio":"16:9","Index":0,"IsExternal":false,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Protocol":"File","PixelFormat":"yuv420p","Level":50,"IsAnamorphic":false,"ExtendedVideoType":"None","ExtendedVideoSubType":"None","ExtendedVideoSubTypeDescription":"None","AttachmentSize":0},{"Codec":"aac","Language":"jpn","TimeBase":"1/1000","Title":"Japanese","DisplayTitle":"Japanese AAC stereo (默认)","DisplayLanguage":"Japanese","IsInterlaced":false,"ChannelLayout":"stereo","BitRate":192000,"Channels":2,"SampleRate":48000,"IsDefault":true,"IsForced":false,"IsHearingImpaired":false,"Profile":"LC","Type":"Audio","Index":1,"IsExternal":false,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Protocol":"File","ExtendedVideoType":"None","ExtendedVideoSubType":"None","ExtendedVideoSubTypeDescription":"None","AttachmentSize":0},{"Codec":"subrip"," 2024/04/18 17:59:02 [warn] 277#277: *3688 js: modify direct play info 2024/04/18 17:59:02 [warn] 277#277: *3688 js: remove transcode config 2024/04/18 17:59:02 [warn] 277#277: *3688 js: 7ms, transfer playbackinfo: {"MediaSources":[{"Size":258739171,"SupportsDirectPlay":true,"Container":"mkv","Name":"家里蹲吸血姬的郁闷 - S01E06 - 怪人云集的圆桌会议","Protocol":"File","Formats":[],"SupportsProbing":false,"HasMixedProtocols":false,"RequiresLooping":false,"Id":"74859721e1d4f9d0ded5192d3d5ca4c2","Path":"/Bangumi/家里蹲吸血姬的郁闷 (2023)/Season 1/家里蹲吸血姬的郁闷 - S01E06 - 怪人云集的圆桌会议.mkv","SupportsDirectStream":true,"RequiresClosing":false,"Bitrate":1435456,"RequiredHttpHeaders":{},"AddApiKeyToDirectStreamUrl":false,"DefaultAudioStreamIndex":1,"IsRemote":false,"SupportsTranscoding":false,"OriginDirectStreamUrl":"/videos/11040/original.mkv?DeviceId=ec3598d9-9d51-4f14-b692-d82eb79461cb&MediaSourceId=74859721e1d4f9d0ded5192d3d5ca4c2&PlaySessionId=68a81a925a4f4b7a8cdcdd2a9e6deb61&api_key=0b0e69e2dab3497a938cdda392c62571","ReadAtNativeFramerate":false,"Type":"Default","IsInfiniteStream":false,"MediaStreams":[{"RealFrameRate":23.976025,"ColorPrimaries":"bt709","IsExternal":false,"ColorTransfer":"bt709","Width":1920,"Protocol":"File","Level":50,"IsAnamorphic":false,"IsInterlaced":false,"IsDefault":true,"AspectRatio":"16:9","TimeBase":"1/1000","Title":"Japanese","IsForced":false,"Language":"jpn","BitDepth":8,"BitRate":1435456,"SupportsExternalStream":false,"AverageFrameRate":23.976025,"ExtendedVideoSubTypeDescription":"None","AttachmentSize":0,"RefFrames":1,"Height":1080,"IsTextSubtitleStream":false,"Codec":"h264","VideoRange":"SDR","Index":0,"ExtendedVideoType":"None","ColorSpace":"bt709","DisplayLanguage":"Japanese","Type":"Video","IsHearingImpaired":false,"Profile":"High","PixelFormat":"yuv420p","DisplayTitle":"1080p H264","NalLengthSize":"4","ExtendedVideoSubType":"None"},{"SampleRate":48000,"IsExternal":false,"Protocol":"File","IsInterlaced":false,"IsDefault":true,"TimeBase":"1/1000","Title":"Japanese","Channels":2,"IsForced":false,"Language":"jpn","BitRate":192000,"SupportsExternalStream":false,"Exten 2024/04/18 17:59:03 [warn] 277#277: *3688 js: cached PlaybackInfo path, will skip excess fetchEmbyFilePath 2024/04/18 17:59:03 [warn] 277#277: *3688 js: mount emby file path: /mnt/media/Bangumi/家里蹲吸血姬的郁闷 (2023)/Season 1/家里蹲吸血姬的郁闷 - S01E06 - 怪人云集的圆桌会议.mkv 2024/04/18 17:59:03 [warn] 277#277: *3688 js: hit isDisableRedirect, not xxxMountPath first: /Movie 2024/04/18 17:59:03 [warn] 277#277: *3688 js: hit isDisableRedirect: ["r.variables.remote_addr",0,["172.","10.","192.","[fd00:"]] 2024/04/18 17:59:03 [warn] 277#277: *3688 js: use original link 2024/04/18 17:59:03 [warn] 277#277: *3688 js: redirectDict add: [Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0:/emby/videos/11040/家里蹲吸血姬的郁闷 - S01E06 - 怪人云集的圆桌会议.mkv] : [@root] 2024/04/18 17:59:03 [warn] 277#277: *3688 js: success: fetchNotificationsAdmin: {"Name":"【emby2Alist】","Description":"hit redirectCache: false, use original link: success"} 2024/04/18 17:59:03 [warn] 277#277: *3688 js: success: fetchSessionsMessage: {"Header":"【emby2Alist】","Text":"hit redirectCache: false, use original link: success","TimeoutMs":0} 2024/04/18 17:59:03 [error] 277#277: *3688 could not find named location "@root", client: 192.168.6.163, server: xxx.example.com, request: "GET /emby/videos/11040/stream/%E5%AE%B6%E9%87%8C%E8%B9%B2%E5%90%B8%E8%A1%80%E5%A7%AC%E7%9A%84%E9%83%81%E9%97%B7%20-%20S01E06%20-%20%E6%80%AA%E4%BA%BA%E4%BA%91%E9%9B%86%E7%9A%84%E5%9C%86%E6%A1%8C%E4%BC%9A%E8%AE%AE.mkv?IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AutoOpenLiveStream=true&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby%20Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&X-Emby-Device-Name=Microsoft%20Edge%20Windows&X-Emby-Language=zh-cn&MediaSourceId=74859721e1d4f9d0ded5192d3d5ca4c2&Static=true&filePath=%252FBangumi%252F%25E5%25AE%25B6%25E9%2587%258C%25E8%25B9%25B2%25E5%2590%25B8%25E8%25A1%2580%25E5%25A7%25AC%25E7%259A%2584%25E9%2583%2581%25E9%2597%25B7%2520(2023)%252FSeason%25201%252F%25E5%25AE%25B6%25E9%2587%258C%25E8%25B9%25B2%25E5%2590%25B8%25E8%25A1%2580%25E5%25A7%25AC%25E7%259A%2584%25E9%2583%2581%25E9%2597%25B7%2520-%2520S01E06%2520-%2520%25E6%2580%25AA%25E4%25BA%25BA%25E4%25BA%2591%25E9%259B%2586%25E7%259A%2584%25E5%259C%2586%25E6%25A1%258C%25E4%25BC%259A%25E8%25AE%25AE.mkv¬Local=0 HTTP/1.1", host: "xxx.example.com" ```

其中 embyMountPath 我有尝试过设置成 [""] 也是不行。

请问是我打开方式不对吗,我整错了什么呢,谢谢!


Edit:一顿研究之后外网播放解决了,可以成功跳转 Alist,已经把修改的配置文件贴上来了,但内网还是不行

chen3861229 commented 6 months ago

location / 下边少了一段,这个是命中了禁用直链规则后要走的内部反代路径

location @root {
      # Proxy main emby/jellyfin traffic
      proxy_pass $emby;
}

多谢提供详细日志及配置,排错方便很多,看日志分析内网的ip判断已经正确了,只是找不到@root反代路径

sgpublic commented 6 months ago

location / 下边少了一段,这个是命中了禁用直链规则后要走的内部反代路径

啊确实没想到是规则漏复制了一段(捂脸),我还一顿研究代码找了半天没找到在哪获取的 @root,加上之后好了,感谢大佬帮助!