bpking1 / embyExternalUrl

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

播放 .ts 格式文件时无法正常播放 #126

Closed sgpublic closed 4 months ago

sgpublic commented 5 months ago

如题,无论是本地直连还是重定向到 alist 都不能正常播放,现象是开始播放之后播放暂停键一直循环为播放/暂停/播放/暂停,看网页上请求似乎一直在请求播放链接,然后打日志不支持 ts 格式,但是我创建 #107 最后解决的时候,当时最新的 commit 是可以的,之后我创建 #122 的时候,当时最新的 commit 其实已经有这个问题了。

老样子贴上日志配置:

constant.js ```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"]; // 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 是否启用了 sign const alistSignEnable = true; // alist 中设置的直链过期时间,以小时为单位 const alistSignExpireTime = 12; // 选填项,用不到保持默认即可 // alist公网地址, 用于需要alist server代理流量的情况, 按需填写 const alistPublicAddr = "https://alist.example.com"; // 字符串头,用于特殊匹配判断 const strHead = { lanIp: ["172.", "10.", "192.", "[fd00:"], // 局域网ip头 // "115": "https://cdnfhnfile.115.com", }; // 路由缓存配置 const routeCacheConfig = { // 总开关,是否开启路由缓存,此为一级缓存,添加阶段为redirect和proxy之前 // 短时间内同客户端访问相同资源不会再做判断和请求alist,有限的防抖措施,出现问题可以关闭此选项 enable: true, // 二级缓存开关,仅针对直链,添加阶段为进入单集详情页,cilentSelfAlistRule中的和首页直接播放的不生效 enableL2: false, // 缓存键表达式,默认为请求参数MediaSourceId,好处是命中范围大,但会导致routeRule中针对设备的规则失效,多个变量可自行组合修改,冒号分隔 keyExpression: "r.args.MediaSourceId:r.args.X-Emby-Device-Id", // "r.args.MediaSourceId:r.args.X-Emby-Device-Id" }; // 路由规则,注意有先后顺序,"proxy"规则优先级最高,其余依次,千万注意规则不要重叠,不然排错十分困难,字幕和图片走了缓存,不在此规则内 // 参数1: 指定处理模式,单规则的默认值为"proxy",但是注意整体规则都不匹配默认值为"redirect",然后下面参数序号-1 // "proxy": 原始媒体服务器处理(中转流量), "redirect": 直链302, "transcode": 转码, "block": 只是屏蔽播放 // 参数2: 分组名,组内为与关系(全部匹配),多个组和没有分组的规则是或关系(任一匹配),然后下面参数序号-1 // 参数3: 匹配类型或来源(字符串参数类型) "filePath": 文件路径(Item.Path), "alistRes": alist返回的链接 // 参数4: 0: startsWith(str), 1: endsWith(str), 2: includes(str), 3: match(/ain/g) // 参数5: 匹配目标,为数组的多个参数时,数组内为或关系(任一匹配) const routeRule = [ // ["filePath", 0, "/mnt/sda1"], // ["filePath", 1, ".mp3"], // ["filePath", 2, "Google"], // ["alistRes", 2, "/NAS/"], // 例如使用alias聚合了nas本地文件,可能会存在卡顿或花屏 // ["filePath", 3, /private/ig], // docker注意必须为host模式,不然此变量全部为内网ip,判断无效,nginx内置变量不带$,客户端地址($remote_addr) ["r.variables.remote_addr", 0, strHead.lanIp], // ["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.UserId", 0, "ac0d220d548f43bbb73cf9b44b2ddf0e"], // 链接入参,用户id // 以下规则代表禁用["Emby Web", "Emby for iOS", "Infuse"]中的[本地挂载文件或alist返回的链接]的115直链功能 // ["115-alist", "r.args.X-Emby-Client", 0, ["Emby Web", "Emby for iOS", "Infuse"]], // 链接入参,客户端类型 // ["115-alist", "alistRes", 0, strHead["115"]], // ["115-local", "r.args.X-Emby-Client", 0, ["Emby Web", "Emby for iOS", "Infuse"]], // ["115-local", "filePath", 0, "/mnt/115"], // 注意非"proxy"无法使用"alistRes"条件,因为没有获取alist直链的过程 // ["proxy", "filePath", 0, "/mnt/sda1"], // ["redirect", "filePath", 0, "/mnt/sda2"], // ["transcode", "filePath", 0, "/mnt/sda3"], // ["transcode", "115-local", "r.args.X-Emby-Client", 0, ["Emby Web", "Emby for iOS", "Infuse"]], // ["transcode", "115-local", "filePath", 0, "/mnt/115"], // ["block", "filePath", 0, "/mnt/sda4"], ]; // 路径映射,会在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内部链接 const redirectStrmLastLinkRule = [ // [0, strHead.lanIp.map(s => "http://" + s)], // [0, alistAddr], // [0, "http:"], // 参数3: 请求验证类型,当前alistAddr不需要此参数 // 参数4: 当前alistAddr不需要此参数,alistSignExpireTime // [0, "http://otheralist1.com", "sign", `${alistToken}:${alistSignExpireTime}`], ]; // 指定客户端自己请求并获取alist直链的规则,代码优先级在redirectStrmLastLinkRule之后 // 特殊情况使用,则此处必须使用域名且公网畅通,用不着请保持默认 // 参数1: 0: startsWith(str), 1: endsWith(str), 2: includes(str), 3: match(/ain/g) // 参数2: 匹配目标,对象为Alist接口返回的链接raw_url // 参数3: 指定转发给客户端的alist的host前缀,兼容sign参数 const cilentSelfAlistRule = [ // "Emby for iOS"和"Infuse"对于115的进度条拖动依赖于此 // 如果nginx为https,则此alist也必须https,浏览器行为客户端会阻止非https请求 // [0, strHead["115"], alistPublicAddr], ]; // !!!实验功能,转码负载均衡,默认false,将按之前逻辑禁止转码处理并移除转码选项参数,与emby配置无关 // 主库和所有从库给用户开启[播放-如有必要,在媒体播放期间允许视频转码]+[倒数7行-允许媒体转换] // type: "nginx", nginx负载均衡,好处是使用简单且内置均衡参数选择,缺点是流量全部经过此服务器, // 且使用条件很苛刻,转码服务组中的媒体id需要和主媒体库中id一致,自行寻找实现主从同步,完全同步后,ApiKey也是一致的 // type: "distributed-media-server", 分布式媒体服务负载均衡(暂未实现均衡),优先利用302真正实现流量的LB,且灵活, // 不区分主从,当前访问服务即为主库,可emby/jellyfin混搭,挂载路径可以不一致,但要求库中的标题和语种一致且原始文件名一致 const transcodeConfig = { enable: false, type: "distributed-media-server", // 负载类型,可选值, ["nginx", "distributed-media-server"] maxNum: 3, // 单机最大转码数量,有助于加速轮询, 参数暂无作用,接口无法查询转码情况,忽略此参数 redirectTransOptEnable: true, // 302的直链文件是否保留码率选择,不保留客户端将无法手动切换至转码 fallbackRouteMode: "redirect", // 降级后路由措施,可选值, ["redirect", "proxy"] // 注意下列host必须全部为公网地址,会302给客户端访问,如果为空数组,将使用当前服务,若参与负载下边手动添加 server: [ { type: "emby", host: "http://yourdomain.com:8096", apiKey: "f839390f50a648fd92108bc11ca6730a", }, { type: "jellyfin", host: "http://yourdomain.com:8097", apiKey: "f839390f50a648fd92108bc11ca6730a", }, // plex和weight参数暂未实现,很难 // { // type: "plex", // host: "http://yourdomain.com: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: false, includeUrl: false, // 链接太长,默认关闭 name: "【emby2Alist】", }; // 对接emby设备控制推送通知消息,目前只发送是否直链成功,此处为统一开关,范围为所有的客户端,通知目标只为当前播放的设备 const embyRedirectSendMessage = { enable: false, header: "【emby2Alist】", timeoutMs: -1, // 消息通知弹窗持续毫秒值 }; // 按路径匹配规则隐藏部分接口返回的items // 参数1: 0: startsWith(str), 1: endsWith(str), 2: includes(str), 3: match(/ain/g) // 参数2: 匹配目标,对象为Item.Path // 参数3: 0: 默认同时过滤下列所有类型接口, 1: 只隐藏[搜索建议(不会过滤搜索接口)]接口, // 2: 只隐藏[更多类似(若当前浏览项目位于规则中,将跳过隐藏)]接口, 3: 只隐藏第三方使用的[海报推荐]接口 const itemHiddenRule = [ // [0, "/mnt/sda1"], // [1, ".mp3", 1], // [2, "Google", 2], // [3, /private/ig], ]; // for js_set function getEmbyHost(r) { return embyHost; } function getTranscodeEnable(r) { return transcodeConfig.enable; } function getTranscodeType(r) { return transcodeConfig.type; } function getImageCachePolicy(r) { return imageCachePolicy; } export default { embyHost, embyMountPath, embyApiKey, routeCacheConfig, routeRule, alistAddr, alistToken, alistSignEnable, alistSignExpireTime, alistPublicAddr, strHead, cilentSelfAlistRule, embyPathMapping, redirectStrmLastLinkRule, embyNotificationsAdmin, embyRedirectSendMessage, itemHiddenRule, transcodeConfig, getEmbyHost, getTranscodeEnable, getTranscodeType, getImageCachePolicy, } ```
网页控制台日志 ``` setSrcIntoPlayer error: [object Object] playbackmanager.js?v=4.9.0.11:1 playbackmanager playback error type: medianotsupported plugin.js?v=4.9.0.11:1 playing url: https://media.example.com/emby/videos/15952/stream/1.7.2%20%E5%8D%8F%E8%AE%AE%E4%B8%8E%E5%88%92%E5%88%86%E5%B1%82%E6%AC%A1%20-%20S01E12%20-%20%E7%AC%AC12%E9%9B%86.mpegts?IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AudioStreamIndex=1&MediaSourceId=85a6811101496de2a4a15b1bbb71fe0c&SubtitleStreamIndex=-1&AutoOpenLiveStream=true&EnableDirectStream=false&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby%20Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&CurrentPlaySessionId=36cc0c1625184248908560b9e27108d2&X-Emby-Device-Name=Microsoft%20Edge%20Windows&X-Emby-Language=zh-cn&EnableDirectPlay=false&Static=true&filePath=%252Fmnt%252Fmedia%252FStudy%252F%25E8%25AE%25A1%25E7%25AE%2597%25E6%259C%25BA%25E7%25BD%2591%25E7%25BB%259C%25EF%25BC%2588%25E7%25AC%25AC8%25E7%2589%2588%25EF%25BC%2589%25E5%25BE%25AE%25E8%25AF%25BE%2520(2021)%252FSeason%25201%252F1.7.2%2520%25E5%258D%258F%25E8%25AE%25AE%25E4%25B8%258E%25E5%2588%2592%25E5%2588%2586%25E5%25B1%2582%25E6%25AC%25A1%2520-%2520S01E12%2520-%2520%25E7%25AC%25AC12%25E9%259B%2586.ts¬Local=0 plugin.js?v=4.9.0.11:1 setCurrentTrackElement Setting new text track index to: -1 plugin.js?v=4.9.0.11:1 mediaStreamTextTracks: 0 plugin.js?v=4.9.0.11:1 setCurrentTrackElement targetIndex: -1, track language: undefined ede.user.js:527 正在重新加载 playbackmanager.js?v=4.9.0.11:1 setSrcIntoPlayer error: [object Object] playbackmanager.js?v=4.9.0.11:1 playbackmanager playback error type: medianotsupported plugin.js?v=4.9.0.11:1 playing url: https://media.example.com/emby/videos/15952/stream/1.7.2%20%E5%8D%8F%E8%AE%AE%E4%B8%8E%E5%88%92%E5%88%86%E5%B1%82%E6%AC%A1%20-%20S01E12%20-%20%E7%AC%AC12%E9%9B%86.mpegts?IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AudioStreamIndex=1&MediaSourceId=85a6811101496de2a4a15b1bbb71fe0c&SubtitleStreamIndex=-1&AutoOpenLiveStream=true&EnableDirectStream=false&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby%20Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&CurrentPlaySessionId=557aa6cc3b854dcb9025a8940202d9d3&X-Emby-Device-Name=Microsoft%20Edge%20Windows&X-Emby-Language=zh-cn&EnableDirectPlay=false&Static=true&filePath=%252Fmnt%252Fmedia%252FStudy%252F%25E8%25AE%25A1%25E7%25AE%2597%25E6%259C%25BA%25E7%25BD%2591%25E7%25BB%259C%25EF%25BC%2588%25E7%25AC%25AC8%25E7%2589%2588%25EF%25BC%2589%25E5%25BE%25AE%25E8%25AF%25BE%2520(2021)%252FSeason%25201%252F1.7.2%2520%25E5%258D%258F%25E8%25AE%25AE%25E4%25B8%258E%25E5%2588%2592%25E5%2588%2586%25E5%25B1%2582%25E6%25AC%25A1%2520-%2520S01E12%2520-%2520%25E7%25AC%25AC12%25E9%259B%2586.ts¬Local=0 plugin.js?v=4.9.0.11:1 setCurrentTrackElement Setting new text track index to: -1 plugin.js?v=4.9.0.11:1 mediaStreamTextTracks: 0 plugin.js?v=4.9.0.11:1 setCurrentTrackElement targetIndex: -1, track language: undefined ede.user.js:527 正在重新加载 playbackmanager.js?v=4.9.0.11:1 setSrcIntoPlayer error: [object Object] playbackmanager.js?v=4.9.0.11:1 playbackmanager playback error type: medianotsupported plugin.js?v=4.9.0.11:1 playing url: https://media.example.com/emby/videos/15952/stream/1.7.2%20%E5%8D%8F%E8%AE%AE%E4%B8%8E%E5%88%92%E5%88%86%E5%B1%82%E6%AC%A1%20-%20S01E12%20-%20%E7%AC%AC12%E9%9B%86.mpegts?IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AudioStreamIndex=1&MediaSourceId=85a6811101496de2a4a15b1bbb71fe0c&SubtitleStreamIndex=-1&AutoOpenLiveStream=true&EnableDirectStream=false&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby%20Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&CurrentPlaySessionId=336e34c6eec242d59a8943dd922858ce&X-Emby-Device-Name=Microsoft%20Edge%20Windows&X-Emby-Language=zh-cn&EnableDirectPlay=false&Static=true&filePath=%252Fmnt%252Fmedia%252FStudy%252F%25E8%25AE%25A1%25E7%25AE%2597%25E6%259C%25BA%25E7%25BD%2591%25E7%25BB%259C%25EF%25BC%2588%25E7%25AC%25AC8%25E7%2589%2588%25EF%25BC%2589%25E5%25BE%25AE%25E8%25AF%25BE%2520(2021)%252FSeason%25201%252F1.7.2%2520%25E5%258D%258F%25E8%25AE%25AE%25E4%25B8%258E%25E5%2588%2592%25E5%2588%2586%25E5%25B1%2582%25E6%25AC%25A1%2520-%2520S01E12%2520-%2520%25E7%25AC%25AC12%25E9%259B%2586.ts¬Local=0 plugin.js?v=4.9.0.11:1 setCurrentTrackElement Setting new text track index to: -1 plugin.js?v=4.9.0.11:1 mediaStreamTextTracks: 0 plugin.js?v=4.9.0.11:1 setCurrentTrackElement targetIndex: -1, track language: undefined ede.user.js:527 正在重新加载 ```
nginx 日志 ``` 2024/04/29 12:50:35 [warn] 729#729: *223840 js: === /emby/Items/15899/PlaybackInfo, the NJS VM is destroyed === 2024/04/29 12:50:35 [warn] 729#729: *223840 js: redirect2Pan, UA: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0 2024/04/29 12:50:35 [warn] 729#729: *223840 js: hit routeCache L1: https://alist.example.com/d/public/emby-media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts?sign=tZkDmZV6TwYDLFzejvPKWkTFjrP3o9mCdiEwW9Payyo=:1714409255 2024/04/29 12:50:35 [warn] 729#729: *223840 js: redirect to: https://alist.example.com/d/public/emby-media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts?sign=tZkDmZV6TwYDLFzejvPKWkTFjrP3o9mCdiEwW9Payyo=:1714409255 2024/04/29 12:50:35 [warn] 729#729: *223840 js: === /emby/videos/15899/6.0 应用层概述 - S06E01 - 第1集.mpegts, the NJS VM is destroyed === 2024/04/29 12:50:37 [notice] 729#729: *223840 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000429, client: 192.168.6.163, server: media.example.com, request: "POST /emby/Items/15899/PlaybackInfo?UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&StartTimeTicks=0&IsPlayback=true&AutoOpenLiveStream=true&AudioStreamIndex=1&SubtitleStreamIndex=-1&EnableDirectPlay=false&EnableDirectStream=false&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&MaxStreamingBitrate=160000000&CurrentPlaySessionId=f66bb22a6a354a9f888e79f5e282205b&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: "media.example.com" 2024/04/29 12:50:37 [warn] 729#729: *223840 js: playbackinfo proxy uri: /proxy/emby/Items/15899/PlaybackInfo 2024/04/29 12:50:37 [warn] 729#729: *223840 js: playbackinfo proxy query string: IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AudioStreamIndex=1&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&SubtitleStreamIndex=-1&AutoOpenLiveStream=true&EnableDirectStream=false&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&CurrentPlaySessionId=f66bb22a6a354a9f888e79f5e282205b&X-Emby-Device-Name=Microsoft Edge Windows&X-Emby-Language=zh-cn&EnableDirectPlay=false 2024/04/29 12:50:37 [info] 729#729: *223840 js: main request headersOut: {} 2024/04/29 12:50:37 [info] 729#729: *223840 js: subrequest headersOut: {"Content-Type":"application/json; charset=utf-8","Content-Length":"2658","Access-Control-Allow-Credentials":"true","Access-Control-Allow-Headers":"Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization","Access-Control-Allow-Methods":"GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Origin":"https://media.example.com","Cross-Origin-Resource-Policy":"cross-origin","Access-Control-Allow-Private-Network":"true","Private-Network-Access-Id":"0e076fcdaecc46a0a8d5fbc154f2f407"} 2024/04/29 12:50:37 [warn] 729#729: *223840 js: origin playbackinfo: {"MediaSources":[{"Protocol":"File","Id":"b847ae9616cab91acc1ce65dacc635f0","Path":"/mnt/media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts","Type":"Default","Container":"mpegts","Size":77424784,"Name":"6.0 应用层概述 - S06E01 - 第1集","IsRemote":false,"HasMixedProtocols":false,"RunTimeTicks":7988064440,"SupportsTranscoding":true,"SupportsDirectStream":false,"SupportsDirectPlay":false,"IsInfiniteStream":false,"RequiresOpening":false,"RequiresClosing":false,"RequiresLooping":false,"SupportsProbing":false,"MediaStreams":[{"Codec":"h264","TimeBase":"1/90000","VideoRange":"SDR","DisplayTitle":"720p H264","NalLengthSize":"0","IsInterlaced":false,"BitRate":775404,"BitDepth":8,"RefFrames":1,"IsDefault":false,"IsForced":false,"IsHearingImpaired":false,"Height":720,"Width":1280,"AverageFrameRate":25,"RealFrameRate":25,"Profile":"High","Type":"Video","AspectRatio":"16:9","Index":0,"IsExternal":false,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Protocol":"File","PixelFormat":"yuv420p","Level":31,"IsAnamorphic":false,"ExtendedVideoType":"None","ExtendedVideoSubType":"None","ExtendedVideoSubTypeDescription":"None","AttachmentSize":0},{"Codec":"aac","Language":"eng","TimeBase":"1/90000","DisplayTitle":"English AAC stereo","DisplayLanguage":"English","IsInterlaced":false,"ChannelLayout":"stereo","BitRate":128098,"Channels":2,"SampleRate":44100,"IsDefault":false,"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}],"Formats":[],"Bitrate":775404,"RequiredHttpHeaders":{},"AddApiKeyToDirectStreamUrl":false,"TranscodingUrl":"/videos/15899/master.m3u8?DeviceId=ec3598d9-9d51-4f14-b692-d82eb79461cb&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&PlaySe 2024/04/29 12:50:37 [warn] 729#729: *223840 js: modify direct play supports 2024/04/29 12:50:37 [warn] 729#729: *223840 js: modify direct play info 2024/04/29 12:50:37 [warn] 729#729: *223840 js: 7ms, transfer playbackinfo: {"MediaSources":[{"Size":77424784,"SupportsDirectPlay":true,"TranscodingContainer":"ts","Container":"mpegts","Name":"6.0 应用层概述 - S06E01 - 第1集","Protocol":"File","Formats":[],"TranscodingSubProtocol":"hls","SupportsProbing":false,"HasMixedProtocols":false,"RequiresLooping":false,"Id":"b847ae9616cab91acc1ce65dacc635f0","Path":"/mnt/media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts","SupportsDirectStream":true,"RequiresClosing":false,"Bitrate":775404,"RequiredHttpHeaders":{},"AddApiKeyToDirectStreamUrl":false,"DefaultAudioStreamIndex":1,"IsRemote":false,"SupportsTranscoding":true,"TranscodingUrl":"/videos/15899/master.m3u8?DeviceId=ec3598d9-9d51-4f14-b692-d82eb79461cb&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&PlaySessionId=49c5928ef85a4dc8aaa53d4ec59e784e&api_key=0b0e69e2dab3497a938cdda392c62571&VideoCodec=h264,h265,hevc,av1&AudioCodec=ac3,mp3,aac&VideoBitrate=159871902&AudioBitrate=128098&MaxWidth=3840&AudioStreamIndex=1&TranscodingMaxAudioChannels=2&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=True&SubtitleStreamIndexes=-1&ManifestSubtitles=vtt&h264-profile=high,main,baseline,constrainedbaseline,high10&h264-level=62&hevc-codectag=hvc1,hev1,hevc,hdmv&TranscodeReasons=ContainerNotSupported,DirectPlayError","ReadAtNativeFramerate":false,"Type":"Default","IsInfiniteStream":false,"MediaStreams":[{"RealFrameRate":25,"IsExternal":false,"Width":1280,"Protocol":"File","Level":31,"IsAnamorphic":false,"IsInterlaced":false,"IsDefault":false,"AspectRatio":"16:9","TimeBase":"1/90000","IsForced":false,"BitDepth":8,"BitRate":775404,"SupportsExternalStream":false,"AverageFrameRate":25,"ExtendedVideoSubTypeDescription":"None","AttachmentSize":0,"RefFrames":1,"Height":720,"IsTextSubtitleStream":false,"Codec":"h264","VideoRange":"SDR","Index":0,"ExtendedVideoType":"None","Type":"Video","IsHearingImpaired":false,"Profile":"High","PixelFormat":"yuv420p","DisplayTitle":"720p H264 2024/04/29 12:50:37 [warn] 729#729: *223840 js: === /emby/Items/15899/PlaybackInfo, the NJS VM is destroyed === 2024/04/29 12:50:37 [warn] 729#729: *223840 js: redirect2Pan, UA: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0 2024/04/29 12:50:37 [warn] 729#729: *223840 js: hit routeCache L1: https://alist.example.com/d/public/emby-media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts?sign=tZkDmZV6TwYDLFzejvPKWkTFjrP3o9mCdiEwW9Payyo=:1714409255 2024/04/29 12:50:37 [warn] 729#729: *223840 js: redirect to: https://alist.example.com/d/public/emby-media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts?sign=tZkDmZV6TwYDLFzejvPKWkTFjrP3o9mCdiEwW9Payyo=:1714409255 2024/04/29 12:50:37 [warn] 729#729: *223840 js: === /emby/videos/15899/6.0 应用层概述 - S06E01 - 第1集.mpegts, the NJS VM is destroyed === 2024/04/29 12:50:39 [notice] 729#729: *223840 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000430, client: 192.168.6.163, server: media.example.com, request: "POST /emby/Items/15899/PlaybackInfo?UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&StartTimeTicks=0&IsPlayback=true&AutoOpenLiveStream=true&AudioStreamIndex=1&SubtitleStreamIndex=-1&EnableDirectPlay=false&EnableDirectStream=false&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&MaxStreamingBitrate=160000000&CurrentPlaySessionId=49c5928ef85a4dc8aaa53d4ec59e784e&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: "media.example.com" 2024/04/29 12:50:39 [warn] 729#729: *223840 js: playbackinfo proxy uri: /proxy/emby/Items/15899/PlaybackInfo 2024/04/29 12:50:39 [warn] 729#729: *223840 js: playbackinfo proxy query string: IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AudioStreamIndex=1&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&SubtitleStreamIndex=-1&AutoOpenLiveStream=true&EnableDirectStream=false&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&CurrentPlaySessionId=49c5928ef85a4dc8aaa53d4ec59e784e&X-Emby-Device-Name=Microsoft Edge Windows&X-Emby-Language=zh-cn&EnableDirectPlay=false 2024/04/29 12:50:39 [info] 729#729: *223840 js: main request headersOut: {} 2024/04/29 12:50:39 [info] 729#729: *223840 js: subrequest headersOut: {"Content-Type":"application/json; charset=utf-8","Content-Length":"2658","Access-Control-Allow-Credentials":"true","Access-Control-Allow-Headers":"Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization","Access-Control-Allow-Methods":"GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Origin":"https://media.example.com","Cross-Origin-Resource-Policy":"cross-origin","Access-Control-Allow-Private-Network":"true","Private-Network-Access-Id":"0e076fcdaecc46a0a8d5fbc154f2f407"} 2024/04/29 12:50:39 [warn] 729#729: *223840 js: origin playbackinfo: {"MediaSources":[{"Protocol":"File","Id":"b847ae9616cab91acc1ce65dacc635f0","Path":"/mnt/media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts","Type":"Default","Container":"mpegts","Size":77424784,"Name":"6.0 应用层概述 - S06E01 - 第1集","IsRemote":false,"HasMixedProtocols":false,"RunTimeTicks":7988064440,"SupportsTranscoding":true,"SupportsDirectStream":false,"SupportsDirectPlay":false,"IsInfiniteStream":false,"RequiresOpening":false,"RequiresClosing":false,"RequiresLooping":false,"SupportsProbing":false,"MediaStreams":[{"Codec":"h264","TimeBase":"1/90000","VideoRange":"SDR","DisplayTitle":"720p H264","NalLengthSize":"0","IsInterlaced":false,"BitRate":775404,"BitDepth":8,"RefFrames":1,"IsDefault":false,"IsForced":false,"IsHearingImpaired":false,"Height":720,"Width":1280,"AverageFrameRate":25,"RealFrameRate":25,"Profile":"High","Type":"Video","AspectRatio":"16:9","Index":0,"IsExternal":false,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Protocol":"File","PixelFormat":"yuv420p","Level":31,"IsAnamorphic":false,"ExtendedVideoType":"None","ExtendedVideoSubType":"None","ExtendedVideoSubTypeDescription":"None","AttachmentSize":0},{"Codec":"aac","Language":"eng","TimeBase":"1/90000","DisplayTitle":"English AAC stereo","DisplayLanguage":"English","IsInterlaced":false,"ChannelLayout":"stereo","BitRate":128098,"Channels":2,"SampleRate":44100,"IsDefault":false,"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}],"Formats":[],"Bitrate":775404,"RequiredHttpHeaders":{},"AddApiKeyToDirectStreamUrl":false,"TranscodingUrl":"/videos/15899/master.m3u8?DeviceId=ec3598d9-9d51-4f14-b692-d82eb79461cb&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&PlaySe 2024/04/29 12:50:39 [warn] 729#729: *223840 js: modify direct play supports 2024/04/29 12:50:39 [warn] 729#729: *223840 js: modify direct play info 2024/04/29 12:50:39 [warn] 729#729: *223840 js: 7ms, transfer playbackinfo: {"MediaSources":[{"Size":77424784,"SupportsDirectPlay":true,"TranscodingContainer":"ts","Container":"mpegts","Name":"6.0 应用层概述 - S06E01 - 第1集","Protocol":"File","Formats":[],"TranscodingSubProtocol":"hls","SupportsProbing":false,"HasMixedProtocols":false,"RequiresLooping":false,"Id":"b847ae9616cab91acc1ce65dacc635f0","Path":"/mnt/media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts","SupportsDirectStream":true,"RequiresClosing":false,"Bitrate":775404,"RequiredHttpHeaders":{},"AddApiKeyToDirectStreamUrl":false,"DefaultAudioStreamIndex":1,"IsRemote":false,"SupportsTranscoding":true,"TranscodingUrl":"/videos/15899/master.m3u8?DeviceId=ec3598d9-9d51-4f14-b692-d82eb79461cb&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&PlaySessionId=9ac49de824944a30a35d8a2cbb7f8105&api_key=0b0e69e2dab3497a938cdda392c62571&VideoCodec=h264,h265,hevc,av1&AudioCodec=ac3,mp3,aac&VideoBitrate=159871902&AudioBitrate=128098&MaxWidth=3840&AudioStreamIndex=1&TranscodingMaxAudioChannels=2&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=True&SubtitleStreamIndexes=-1&ManifestSubtitles=vtt&h264-profile=high,main,baseline,constrainedbaseline,high10&h264-level=62&hevc-codectag=hvc1,hev1,hevc,hdmv&TranscodeReasons=ContainerNotSupported,DirectPlayError","ReadAtNativeFramerate":false,"Type":"Default","IsInfiniteStream":false,"MediaStreams":[{"RealFrameRate":25,"IsExternal":false,"Width":1280,"Protocol":"File","Level":31,"IsAnamorphic":false,"IsInterlaced":false,"IsDefault":false,"AspectRatio":"16:9","TimeBase":"1/90000","IsForced":false,"BitDepth":8,"BitRate":775404,"SupportsExternalStream":false,"AverageFrameRate":25,"ExtendedVideoSubTypeDescription":"None","AttachmentSize":0,"RefFrames":1,"Height":720,"IsTextSubtitleStream":false,"Codec":"h264","VideoRange":"SDR","Index":0,"ExtendedVideoType":"None","Type":"Video","IsHearingImpaired":false,"Profile":"High","PixelFormat":"yuv420p","DisplayTitle":"720p H264 2024/04/29 12:50:39 [warn] 729#729: *223840 js: === /emby/Items/15899/PlaybackInfo, the NJS VM is destroyed === 2024/04/29 12:50:39 [warn] 729#729: *223840 js: redirect2Pan, UA: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0 2024/04/29 12:50:39 [warn] 729#729: *223840 js: hit routeCache L1: https://alist.example.com/d/public/emby-media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts?sign=tZkDmZV6TwYDLFzejvPKWkTFjrP3o9mCdiEwW9Payyo=:1714409255 2024/04/29 12:50:39 [warn] 729#729: *223840 js: redirect to: https://alist.example.com/d/public/emby-media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts?sign=tZkDmZV6TwYDLFzejvPKWkTFjrP3o9mCdiEwW9Payyo=:1714409255 2024/04/29 12:50:39 [warn] 729#729: *223840 js: === /emby/videos/15899/6.0 应用层概述 - S06E01 - 第1集.mpegts, the NJS VM is destroyed === 2024/04/29 12:50:42 [warn] 742#742: *224745 js: itemsFilter before: 1 2024/04/29 12:50:42 [warn] 742#742: *224745 js: itemsFilter flag: searchSuggest 2024/04/29 12:50:42 [warn] 742#742: *224745 js: itemsFilter after: 1 2024/04/29 12:50:42 [warn] 742#742: *224745 js: === /emby/Users/b9f7a0d7f8cd4ac9bd614150dde7ff95/Items, the NJS VM is destroyed === 2024/04/29 12:50:42 [notice] 741#741: *224743 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000431, client: 192.168.6.163, server: media.example.com, request: "POST /emby/Items/15899/PlaybackInfo?UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&StartTimeTicks=0&IsPlayback=true&AutoOpenLiveStream=true&AudioStreamIndex=1&SubtitleStreamIndex=-1&EnableDirectPlay=false&EnableDirectStream=false&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&MaxStreamingBitrate=160000000&CurrentPlaySessionId=9ac49de824944a30a35d8a2cbb7f8105&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: "media.example.com" 2024/04/29 12:50:42 [warn] 741#741: *224743 js: playbackinfo proxy uri: /proxy/emby/Items/15899/PlaybackInfo 2024/04/29 12:50:42 [warn] 741#741: *224743 js: playbackinfo proxy query string: IsPlayback=true&MaxStreamingBitrate=160000000&X-Emby-Client-Version=4.9.0.11&reqformat=json&AudioStreamIndex=1&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&SubtitleStreamIndex=-1&AutoOpenLiveStream=true&EnableDirectStream=false&X-Emby-Token=0b0e69e2dab3497a938cdda392c62571&StartTimeTicks=0&X-Emby-Device-Id=ec3598d9-9d51-4f14-b692-d82eb79461cb&X-Emby-Client=Emby Web&UserId=b9f7a0d7f8cd4ac9bd614150dde7ff95&CurrentPlaySessionId=9ac49de824944a30a35d8a2cbb7f8105&X-Emby-Device-Name=Microsoft Edge Windows&X-Emby-Language=zh-cn&EnableDirectPlay=false 2024/04/29 12:50:42 [info] 741#741: *224743 js: main request headersOut: {} 2024/04/29 12:50:42 [info] 741#741: *224743 js: subrequest headersOut: {"Content-Type":"application/json; charset=utf-8","Content-Length":"2658","Access-Control-Allow-Credentials":"true","Access-Control-Allow-Headers":"Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization","Access-Control-Allow-Methods":"GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Origin":"https://media.example.com","Cross-Origin-Resource-Policy":"cross-origin","Access-Control-Allow-Private-Network":"true","Private-Network-Access-Id":"0e076fcdaecc46a0a8d5fbc154f2f407"} 2024/04/29 12:50:42 [warn] 741#741: *224743 js: origin playbackinfo: {"MediaSources":[{"Protocol":"File","Id":"b847ae9616cab91acc1ce65dacc635f0","Path":"/mnt/media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts","Type":"Default","Container":"mpegts","Size":77424784,"Name":"6.0 应用层概述 - S06E01 - 第1集","IsRemote":false,"HasMixedProtocols":false,"RunTimeTicks":7988064440,"SupportsTranscoding":true,"SupportsDirectStream":false,"SupportsDirectPlay":false,"IsInfiniteStream":false,"RequiresOpening":false,"RequiresClosing":false,"RequiresLooping":false,"SupportsProbing":false,"MediaStreams":[{"Codec":"h264","TimeBase":"1/90000","VideoRange":"SDR","DisplayTitle":"720p H264","NalLengthSize":"0","IsInterlaced":false,"BitRate":775404,"BitDepth":8,"RefFrames":1,"IsDefault":false,"IsForced":false,"IsHearingImpaired":false,"Height":720,"Width":1280,"AverageFrameRate":25,"RealFrameRate":25,"Profile":"High","Type":"Video","AspectRatio":"16:9","Index":0,"IsExternal":false,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Protocol":"File","PixelFormat":"yuv420p","Level":31,"IsAnamorphic":false,"ExtendedVideoType":"None","ExtendedVideoSubType":"None","ExtendedVideoSubTypeDescription":"None","AttachmentSize":0},{"Codec":"aac","Language":"eng","TimeBase":"1/90000","DisplayTitle":"English AAC stereo","DisplayLanguage":"English","IsInterlaced":false,"ChannelLayout":"stereo","BitRate":128098,"Channels":2,"SampleRate":44100,"IsDefault":false,"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}],"Formats":[],"Bitrate":775404,"RequiredHttpHeaders":{},"AddApiKeyToDirectStreamUrl":false,"TranscodingUrl":"/videos/15899/master.m3u8?DeviceId=ec3598d9-9d51-4f14-b692-d82eb79461cb&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&PlaySe 2024/04/29 12:50:42 [warn] 741#741: *224743 js: modify direct play supports 2024/04/29 12:50:42 [warn] 741#741: *224743 js: modify direct play info 2024/04/29 12:50:42 [warn] 741#741: *224743 js: 6ms, transfer playbackinfo: {"MediaSources":[{"Size":77424784,"SupportsDirectPlay":true,"TranscodingContainer":"ts","Container":"mpegts","Name":"6.0 应用层概述 - S06E01 - 第1集","Protocol":"File","Formats":[],"TranscodingSubProtocol":"hls","SupportsProbing":false,"HasMixedProtocols":false,"RequiresLooping":false,"Id":"b847ae9616cab91acc1ce65dacc635f0","Path":"/mnt/media/Study/计算机网络(第8版)微课 (2021)/Season 6/6.0 应用层概述 - S06E01 - 第1集.ts","SupportsDirectStream":true,"RequiresClosing":false,"Bitrate":775404,"RequiredHttpHeaders":{},"AddApiKeyToDirectStreamUrl":false,"DefaultAudioStreamIndex":1,"IsRemote":false,"SupportsTranscoding":true,"TranscodingUrl":"/videos/15899/master.m3u8?DeviceId=ec3598d9-9d51-4f14-b692-d82eb79461cb&MediaSourceId=b847ae9616cab91acc1ce65dacc635f0&PlaySessionId=1b902c64c3a84d87b3467a4892f286de&api_key=0b0e69e2dab3497a938cdda392c62571&VideoCodec=h264,h265,hevc,av1&AudioCodec=ac3,mp3,aac&VideoBitrate=159871902&AudioBitrate=128098&MaxWidth=3840&AudioStreamIndex=1&TranscodingMaxAudioChannels=2&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=True&SubtitleStreamIndexes=-1&ManifestSubtitles=vtt&h264-profile=high,main,baseline,constrainedbaseline,high10&h264-level=62&hevc-codectag=hvc1,hev1,hevc,hdmv&TranscodeReasons=ContainerNotSupported,DirectPlayError","ReadAtNativeFramerate":false,"Type":"Default","IsInfiniteStream":false,"MediaStreams":[{"RealFrameRate":25,"IsExternal":false,"Width":1280,"Protocol":"File","Level":31,"IsAnamorphic":false,"IsInterlaced":false,"IsDefault":false,"AspectRatio":"16:9","TimeBase":"1/90000","IsForced":false,"BitDepth":8,"BitRate":775404,"SupportsExternalStream":false,"AverageFrameRate":25,"ExtendedVideoSubTypeDescription":"None","AttachmentSize":0,"RefFrames":1,"Height":720,"IsTextSubtitleStream":false,"Codec":"h264","VideoRange":"SDR","Index":0,"ExtendedVideoType":"None","Type":"Video","IsHearingImpaired":false,"Profile":"High","PixelFormat":"yuv420p","DisplayTitle":"720p H264 ```
nginx 配置 listen_https_server.conf ```conf listen 443 ssl; listen [::]:443 ssl; listen 19443 ssl proxy_protocol; listen [::]:19443 ssl proxy_protocol; ssl_certificate $SSL_PEM; ssl_certificate_key $SSL_KEY; 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; ``` listen_location.conf ```conf proxy_set_header Host $host; proxy_set_header X-Real-IP $REAL_REMOTE_ADDR; proxy_set_header X-Forwarded-For $REAL_X_FORWARDED_FOR; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Protocol $scheme; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_redirect off; proxy_buffering off; ``` media.conf ```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:4M timeout=4h evict; js_shared_dict_zone zone=routeL1Dict:1M timeout=15m evict; js_shared_dict_zone zone=routeL2Dict:4M timeout=15m evict; # js_shared_dict_zone zone=routeL3Dict:8M timeout=15m evict; js_shared_dict_zone zone=idemDict:512K timeout=10s 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 media.example.com; include /etc/nginx/common.d/listen_http.conf; } upstream transcode_group { least_conn; server 127.0.0.1:8096; } server { server_name media.example.com; include /etc/nginx/common.d/listen_https_server.conf; js_set $emby config.getEmbyHost; #emby/jellyfin address js_set $transcodeEnable config.getTranscodeEnable; js_set $transcodeType config.getTranscodeType; 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'; # Proxy sockets traffic for jellyfin-mpv-shim and webClient location ~* /(socket|embywebsocket) { include /etc/nginx/common.d/listen_location.conf; # Proxy emby/jellyfin Websockets traffic proxy_pass $emby; ## WEBSOCKET SETTINGS ## Used to pass two way real time info to and from emby and the client. proxy_connect_timeout 1h; proxy_send_timeout 1h; proxy_read_timeout 1h; tcp_nodelay on; ## Sends data as fast as it can not buffering large chunks, saves about 200ms per request. } # Cache the Subtitles location ~* /videos/(.*)/Subtitles { include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; proxy_cache emby_subtitles; proxy_cache_revalidate on; proxy_cache_lock_timeout 10s; proxy_cache_lock on; proxy_cache_valid 200 30d; proxy_cache_key $request_uri; add_header X-Cache-Status $upstream_cache_status; # This is only to check if cache is working } # 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.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; js_content emby2Pan.transferPlaybackInfo; add_header X-Proxy-Success true; # for debug } # 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; } set $flag backdropSuggest; if ($arg_ImageTypes ~* Backdrop) { 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 ~* "useProxy=1") { proxy_pass $emby; break; } set $flag ""; if ($transcodeEnable = true) { set $flag "${flag}1"; } if ($transcodeType = 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 ($transcodeEnable = true) { js_content transcode.syncDelete; break; } include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } # Sessions Playing Stat location ~* /Sessions/Playing { if ($transcodeEnable = 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 ~ / { include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } location @root { include /etc/nginx/common.d/listen_location.conf; proxy_pass $emby; } } ```

示例文件:视频.ts

chen3861229 commented 5 months ago

感谢提供的issus十分清晰,不过示例文件只有一小时有效期过期了,如果方便的话,能换个地址吗?ts文件貌似不太好找

sgpublic commented 5 months ago

感谢提供的issus十分清晰,不过示例文件只有一小时有效期过期了,如果方便的话,能换个地址吗?ts文件貌似不太好找

https://www.alipan.com/s/jTN4kWuZgju ,改后缀为 ts 即可

chen3861229 commented 5 months ago

测试了下,是浏览器Web的格式支持很少,不支持这个格式的,浏览器控制台也是报了视频编码格式不支持,需要用对应平台客户端播放,普通的HLS的ts视频Web是可以播放的 image 以下是windows客户端 image

sgpublic commented 5 months ago

但是如果不经过 emby2Alist,emby 网页上是能正常播放的,过了 emby2Alist 连局域网直连播放都不行

chen3861229 commented 5 months ago

原始媒体服务因为是走了转码,转容器了,因为这个项目优先保证能直链成功,转码比较费服务器性能,playbackinfo的反代中强制修改为了直接播放 image

sgpublic commented 5 months ago

原来如此,总结:尽量不要使用 ts 格式

chen3861229 commented 5 months ago

暂时需要手动指定下允许走转码的路由路径, 之后我想办法看能不能提供个选项出来,之前也有人反馈过播放成功率低,如果能接受原始媒体服务走转码就是和没反代效果一样了 研究了下,依靠 emby 自己的判断,Web浏览器八成媒体会被走转码而不管格式支不支持播放,因为选择了低码率后所有的播放都是传递判断条件低于已选择的码率被转码,影响较大,所以暂时不会加这个开关了,还是用对应平台客户端体验比较好

const routeRule = [
  ["transcode", "filePath", 0, "/mnt/media/Study/计算机网络(第8版)微课 (2021)"],
];
const transcodeConfig = {
  enable: true
}
chen3861229 commented 5 months ago

其实最简单是还是用各平台的客户端比较方便,直接硬解播放的支持媒体格式多很多,修改版的官方客户端貌似都是内置的lib mpv