fix: stubtitle
This commit is contained in:
@@ -101,8 +101,6 @@ background-color: rgba(0, 0, 0, 0.5);
|
|||||||
color: white;
|
color: white;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
text-shadow: 1px 1px 2px black;
|
text-shadow: 1px 1px 2px black;
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.3s ease-in-out;
|
|
||||||
display: inline-block`;
|
display: inline-block`;
|
||||||
|
|
||||||
const SUBTITLE_ORIGIN_STYLE = `font-size: clamp(1.5rem, 3cqw, 3rem);`;
|
const SUBTITLE_ORIGIN_STYLE = `font-size: clamp(1.5rem, 3cqw, 3rem);`;
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ export class BilingualSubtitleManager {
|
|||||||
#formattedSubtitles = [];
|
#formattedSubtitles = [];
|
||||||
#translationService;
|
#translationService;
|
||||||
#captionWindowEl = null;
|
#captionWindowEl = null;
|
||||||
|
#paperEl = null;
|
||||||
#currentSubtitleIndex = -1;
|
#currentSubtitleIndex = -1;
|
||||||
#preTranslateSeconds = 100;
|
#preTranslateSeconds = 100;
|
||||||
#setting = {};
|
#setting = {};
|
||||||
|
#isAdPlaying = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
@@ -56,6 +58,14 @@ export class BilingualSubtitleManager {
|
|||||||
this.#formattedSubtitles = [];
|
this.#formattedSubtitles = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新广告播放状态。
|
||||||
|
*/
|
||||||
|
setIsAdPlaying(isPlaying) {
|
||||||
|
this.#isAdPlaying = isPlaying;
|
||||||
|
this.onTimeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建并配置用于显示字幕的 DOM 元素。
|
* 创建并配置用于显示字幕的 DOM 元素。
|
||||||
*/
|
*/
|
||||||
@@ -68,6 +78,7 @@ export class BilingualSubtitleManager {
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
left: "0",
|
left: "0",
|
||||||
top: "0",
|
top: "0",
|
||||||
|
pointerEvents: "none",
|
||||||
});
|
});
|
||||||
|
|
||||||
const paper = document.createElement("div");
|
const paper = document.createElement("div");
|
||||||
@@ -81,16 +92,20 @@ export class BilingualSubtitleManager {
|
|||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
containerType: "inline-size",
|
containerType: "inline-size",
|
||||||
zIndex: "2147483647",
|
zIndex: "2147483647",
|
||||||
|
pointerEvents: "auto",
|
||||||
|
display: "none",
|
||||||
});
|
});
|
||||||
|
this.#paperEl = paper;
|
||||||
|
|
||||||
this.#captionWindowEl = document.createElement("div");
|
this.#captionWindowEl = document.createElement("div");
|
||||||
this.#captionWindowEl.className = `kiss-caption-window`;
|
this.#captionWindowEl.className = `kiss-caption-window`;
|
||||||
this.#captionWindowEl.style.cssText = this.#setting.windowStyle;
|
this.#captionWindowEl.style.cssText = this.#setting.windowStyle;
|
||||||
this.#captionWindowEl.style.pointerEvents = "auto";
|
this.#captionWindowEl.style.pointerEvents = "auto";
|
||||||
this.#captionWindowEl.style.cursor = "grab";
|
this.#captionWindowEl.style.cursor = "grab";
|
||||||
|
this.#captionWindowEl.style.opacity = "1";
|
||||||
|
|
||||||
paper.appendChild(this.#captionWindowEl);
|
this.#paperEl.appendChild(this.#captionWindowEl);
|
||||||
container.appendChild(paper);
|
container.appendChild(this.#paperEl);
|
||||||
|
|
||||||
const videoContainer = this.#videoEl.parentElement?.parentElement;
|
const videoContainer = this.#videoEl.parentElement?.parentElement;
|
||||||
if (!videoContainer) {
|
if (!videoContainer) {
|
||||||
@@ -101,7 +116,7 @@ export class BilingualSubtitleManager {
|
|||||||
videoContainer.style.position = "relative";
|
videoContainer.style.position = "relative";
|
||||||
videoContainer.appendChild(container);
|
videoContainer.appendChild(container);
|
||||||
|
|
||||||
this.#enableDragging(paper, container, this.#captionWindowEl);
|
this.#enableDragging(this.#paperEl, container, this.#captionWindowEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,7 +245,12 @@ export class BilingualSubtitleManager {
|
|||||||
* @param {object | null} subtitle - 字幕对象,或 null 用于清空。
|
* @param {object | null} subtitle - 字幕对象,或 null 用于清空。
|
||||||
*/
|
*/
|
||||||
#updateCaptionDisplay(subtitle) {
|
#updateCaptionDisplay(subtitle) {
|
||||||
if (!this.#captionWindowEl) return;
|
if (!this.#paperEl || !this.#captionWindowEl) return;
|
||||||
|
|
||||||
|
if (this.#isAdPlaying) {
|
||||||
|
this.#paperEl.style.display = "none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (subtitle) {
|
if (subtitle) {
|
||||||
const p1 = document.createElement("p");
|
const p1 = document.createElement("p");
|
||||||
@@ -247,9 +267,9 @@ export class BilingualSubtitleManager {
|
|||||||
this.#captionWindowEl.replaceChildren(p2);
|
this.#captionWindowEl.replaceChildren(p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#captionWindowEl.style.opacity = "1";
|
this.#paperEl.style.display = "block";
|
||||||
} else {
|
} else {
|
||||||
this.#captionWindowEl.style.opacity = "0";
|
this.#paperEl.style.display = "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { i18n } from "../config";
|
|||||||
const VIDEO_SELECT = "#container video";
|
const VIDEO_SELECT = "#container video";
|
||||||
const CONTORLS_SELECT = ".ytp-right-controls";
|
const CONTORLS_SELECT = ".ytp-right-controls";
|
||||||
const YT_CAPTION_SELECT = "#ytp-caption-window-container";
|
const YT_CAPTION_SELECT = "#ytp-caption-window-container";
|
||||||
|
const YT_AD_SELECT = ".video-ads";
|
||||||
|
|
||||||
class YouTubeCaptionProvider {
|
class YouTubeCaptionProvider {
|
||||||
#setting = {};
|
#setting = {};
|
||||||
@@ -45,6 +46,7 @@ class YouTubeCaptionProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("yt-navigate-finish", () => {
|
window.addEventListener("yt-navigate-finish", () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.#toggleButton) {
|
if (this.#toggleButton) {
|
||||||
@@ -54,9 +56,46 @@ class YouTubeCaptionProvider {
|
|||||||
this.#doubleClick();
|
this.#doubleClick();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.#waitForElement(CONTORLS_SELECT, (ytControls) =>
|
this.#waitForElement(CONTORLS_SELECT, (ytControls) =>
|
||||||
this.#injectToggleButton(ytControls)
|
this.#injectToggleButton(ytControls)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.#waitForElement(YT_AD_SELECT, (adContainer) => {
|
||||||
|
this.#moAds(adContainer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#moAds(adContainer) {
|
||||||
|
const adSlector = ".ytp-ad-player-overlay-layout";
|
||||||
|
const observer = new MutationObserver((mutations) => {
|
||||||
|
for (const mutation of mutations) {
|
||||||
|
if (mutation.type === "childList") {
|
||||||
|
mutation.addedNodes.forEach((node) => {
|
||||||
|
if (node.nodeType === 1 && node.matches(adSlector)) {
|
||||||
|
logger.debug("Youtube Provider: AD start playing!", node);
|
||||||
|
// todo: 顺带把广告快速跳过
|
||||||
|
if (this.#managerInstance) {
|
||||||
|
this.#managerInstance.setIsAdPlaying(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mutation.removedNodes.forEach((node) => {
|
||||||
|
if (node.nodeType === 1 && node.matches(adSlector)) {
|
||||||
|
logger.debug("Youtube Provider: Ad ends!");
|
||||||
|
if (this.#managerInstance) {
|
||||||
|
this.#managerInstance.setIsAdPlaying(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(adContainer, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#waitForElement(selector, callback) {
|
#waitForElement(selector, callback) {
|
||||||
@@ -517,6 +556,7 @@ class YouTubeCaptionProvider {
|
|||||||
|
|
||||||
let subtitles = this.#processSubtitles({ flatEvents });
|
let subtitles = this.#processSubtitles({ flatEvents });
|
||||||
const isPoor = this.#isQualityPoor(subtitles);
|
const isPoor = this.#isQualityPoor(subtitles);
|
||||||
|
logger.debug("Youtube Provider: isQualityPoor", { isPoor, subtitles });
|
||||||
if (isPoor) {
|
if (isPoor) {
|
||||||
subtitles = this.#processSubtitles({ flatEvents, usePause: true });
|
subtitles = this.#processSubtitles({ flatEvents, usePause: true });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user