From 43d6ceaefa9ba47e13a5bc833829ec69b5a6d294 Mon Sep 17 00:00:00 2001 From: Izumiko Date: Mon, 4 Nov 2024 07:34:44 +0000 Subject: [PATCH] deploy: 6b687e9030c6185364fc98b299f4fca72f43973a --- ede.user.js | 79 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/ede.user.js b/ede.user.js index 5d0fdbf..eb35293 100644 --- a/ede.user.js +++ b/ede.user.js @@ -3,7 +3,7 @@ // @description Jellyfin弹幕插件 // @namespace https://github.com/RyoLee // @author RyoLee -// @version 1.50 +// @version 1.51 // @copyright 2022, RyoLee (https://github.com/RyoLee) // @license MIT; https://raw.githubusercontent.com/Izumiko/jellyfin-danmaku/jellyfin/LICENSE // @icon https://github.githubassets.com/pinned-octocat.svg @@ -53,6 +53,7 @@ const mediaContainerQueryStr = "div[data-type='video-osd']"; const mediaQueryStr = 'video'; + let isNewJellyfin = true; let itemId = ''; // Intercept XMLHttpRequest @@ -850,8 +851,20 @@ let playingInfo = null; while (!playingInfo) { await new Promise((resolve) => setTimeout(resolve, 200)); - // params: userId, itemId - playingInfo = await ApiClient.getItem("", itemId); + if (isNewJellyfin) { + // params: userId, itemId + playingInfo = await ApiClient.getItem(ApiClient.getCurrentUserId(), itemId); + } else { + let sessionInfo = await ApiClient.getSessions({ + userId: ApiClient.getCurrentUserId(), + deviceId: ApiClient.deviceId(), + }); + if (!sessionInfo[0].NowPlayingItem) { + await new Promise(resolve => setTimeout(resolve, 150)); + continue; + } + playingInfo = sessionInfo[0].NowPlayingItem; + } } showDebugInfo('获取Item信息成功: ' + (playingInfo.SeriesName || playingInfo.Name)); return playingInfo; @@ -868,7 +881,10 @@ "Accept": "application/json" }, onload: function (response) { - resolve(response.responseText); + response.json = () => Promise.resolve(JSON.parse(response.responseText)); + response.text = () => Promise.resolve(response.responseText); + response.ok = response.status >= 200 && response.status < 300; + resolve(response); }, onerror: function (error) { reject(error); @@ -933,7 +949,7 @@ let searchUrl = apiPrefix + '/api/v2/search/episodes?anime=' + animeName + '&withRelated=true'; let animaInfo = await makeGetRequest(searchUrl) - .then((response) => isInTampermonkey ? JSON.parse(response) : response.json()) + .then((response) => response.json()) .catch((error) => { showDebugInfo('查询失败:', error); return null; @@ -944,7 +960,7 @@ if (animeName?.length > 0) { searchUrl = apiPrefix + '/api/v2/search/episodes?anime=' + animeName + '&withRelated=true'; animaInfo = await makeGetRequest(searchUrl) - .then((response) => isInTampermonkey ? JSON.parse(response) : response.json()) + .then((response) => response.json()) .catch((error) => { showDebugInfo('查询失败:', error); return null; @@ -1008,7 +1024,7 @@ const url_ext = apiPrefix + '/api/v2/extcomment?url='; try { let response = await makeGetRequest(url_all); - let data = isInTampermonkey ? JSON.parse(response) : await response.json(); + let data = await response.json(); const matchBili = /^\[BiliBili\]/; let hasBili = false; if ((danmakuFilter & 1) !== 1) { @@ -1021,7 +1037,7 @@ } let comments = data.comments; response = await makeGetRequest(url_related); - data = isInTampermonkey ? JSON.parse(response) : await response.json(); + data = await response.json(); showDebugInfo('第三方弹幕源个数:' + data.relateds.length); if (data.relateds.length > 0) { @@ -1044,7 +1060,7 @@ // 获取第三方弹幕 await Promise.all(src.map(async (s) => { const response = await makeGetRequest(url_ext + encodeURIComponent(s)); - const data = isInTampermonkey ? JSON.parse(response) : await response.json(); + const data = await response.json(); comments = comments.concat(data.comments); })); } @@ -1062,7 +1078,7 @@ for (let i = 0; i < 2; i++) { try { const response = await makeGetRequest(url); - const data = isInTampermonkey ? JSON.parse(response) : await response.json(); + const data = await response.json(); showDebugInfo('弹幕下载成功: ' + data.comments.length); return data.comments; } catch (error) { @@ -1083,7 +1099,7 @@ async function getCommentsByPluginApi(jellyfinItemId) { const path = window.location.pathname.replace(/\/web\/(index\.html)?/, '/api/danmu/'); const url = window.location.origin + path + jellyfinItemId + '/raw'; - const response = await makeGetRequest(url); + const response = await fetch(url); if (!response.ok) { return null; } @@ -1498,12 +1514,29 @@ }); }; + const compareVersions = (version1, version2) => { + if (typeof version1 !== 'string') return -1; + if (typeof version2 !== 'string') return 1; + const v1 = version1.split('.').map(Number); + const v2 = version2.split('.').map(Number); + + for (let i = 0; i < Math.max(v1.length, v2.length); i++) { + const n1 = v1[i] || 0; + const n2 = v2[i] || 0; + + if (n1 > n2) return 1; + if (n1 < n2) return -1; + } + + return 0; + } + waitForElement('.htmlvideoplayer').then(() => { if (!window.ede) { window.ede = new EDE(); - var materialIcon = document.querySelector('.material-icons'); - var fontFamily = window.getComputedStyle(materialIcon).fontFamily; + const materialIcon = document.querySelector('.material-icons'); + const fontFamily = window.getComputedStyle(materialIcon).fontFamily; if (fontFamily === '"Font Awesome 6 Pro"') { danmaku_icons = ['fa-comment-slash', 'fa-comment']; log_icons = ['fa-toilet-paper-slash', 'fa-toilet-paper']; @@ -1514,12 +1547,20 @@ } (async () => { - let retry = 0; - while (!itemId) { - await new Promise((resolve) => setTimeout(resolve, 200)); - retry++; - if (retry > 10) { - throw new Error('获取itemId失败'); + isNewJellyfin = compareVersions(ApiClient?._appVersion, '10.10.0') >= 0; + // showDebugInfo(`isNewJellyfin: ${isNewJellyfin}`); + if (isNewJellyfin) { + let retry = 0; + while (!itemId) { + await new Promise((resolve) => setTimeout(resolve, 200)); + retry++; + if (retry > 10) { + throw new Error('获取itemId失败'); + } + } + } else { + while (!(await ApiClient.getSessions())) { + await new Promise((resolve) => setTimeout(resolve, 200)); } }