mirror of
https://github.com/NohamR/safari-internal-js.git
synced 2026-10-11 02:49:41 +00:00
Add 27.0 js src
This commit is contained in:
202
27.0/js/media/YouTubeCaptionQuirk.js
Normal file
202
27.0/js/media/YouTubeCaptionQuirk.js
Normal file
@@ -0,0 +1,202 @@
|
||||
//# sourceURL=__InjectedScript_YouTubeCaptionQuirk.js
|
||||
(function () {
|
||||
"use strict";
|
||||
class CaptionMirror {
|
||||
static _instances = new WeakMap();
|
||||
constructor(video) {
|
||||
let oldMirror = CaptionMirror._instances.get(video);
|
||||
if (oldMirror) {
|
||||
oldMirror.invalidate();
|
||||
CaptionMirror._instances.delete(video);
|
||||
}
|
||||
CaptionMirror._instances.set(video, this);
|
||||
this._video = video;
|
||||
this._player = video.parentElement.parentElement;
|
||||
this._captionWindowSelector = ".ytp-caption-window-container";
|
||||
this._mirrorTrack = video.addTextTrack("forced", "YouTube Captions");
|
||||
this._mirrorTrack.mode = "hidden";
|
||||
this._captionObserver = null;
|
||||
this._waitObserver = null;
|
||||
this._onCaptionsTrackListChanged = () => this._syncTrackList();
|
||||
this._onCaptionsChanged = () => this._syncTrackList();
|
||||
this._player.addEventListener(
|
||||
"onCaptionsTrackListChanged",
|
||||
this._onCaptionsTrackListChanged,
|
||||
);
|
||||
this._player.addEventListener("captionschanged", this._onCaptionsChanged);
|
||||
navigator.mediaSession.setActionHandler("togglecaptions", (details) =>
|
||||
this._handleMediaSessionAction(details),
|
||||
);
|
||||
navigator.mediaSession.setActionHandler("selectcaptiontrack", (details) =>
|
||||
this._handleMediaSessionAction(details),
|
||||
);
|
||||
this._onPresentationModeChanged = () =>
|
||||
this._handlePresentationModeChanged();
|
||||
this._video.addEventListener(
|
||||
"webkitpresentationmodechanged",
|
||||
this._onPresentationModeChanged,
|
||||
);
|
||||
this._attachCaptionWindowObserver();
|
||||
this._syncTrackList();
|
||||
}
|
||||
invalidate() {
|
||||
if (this._captionObserver) {
|
||||
this._captionObserver.disconnect();
|
||||
this._captionObserver = null;
|
||||
}
|
||||
if (this._waitObserver) {
|
||||
this._waitObserver.disconnect();
|
||||
this._waitObserver = null;
|
||||
}
|
||||
this._mirrorTrack.mode = "disabled";
|
||||
this._player.removeEventListener(
|
||||
"onCaptionsTrackListChanged",
|
||||
this._onCaptionsTrackListChanged,
|
||||
);
|
||||
this._player.removeEventListener(
|
||||
"captionschanged",
|
||||
this._onCaptionsChanged,
|
||||
);
|
||||
this._video.removeEventListener(
|
||||
"webkitpresentationmodechanged",
|
||||
this._onPresentationModeChanged,
|
||||
);
|
||||
}
|
||||
_syncTrackList() {
|
||||
var trackList = this._getTrackList();
|
||||
var activeTrack = this._getActiveTrack();
|
||||
navigator.mediaSession.captionTracks =
|
||||
trackList?.map((track) => {
|
||||
return {
|
||||
label: track.displayName,
|
||||
language: track.languageCode,
|
||||
enabled: this._areTracksEqual(track, activeTrack),
|
||||
};
|
||||
}) ?? [];
|
||||
navigator.mediaSession.captionsEnabled = this._player.isSubtitlesOn();
|
||||
}
|
||||
_syncCues(captionWindowContainer) {
|
||||
while (this._mirrorTrack.cues?.length)
|
||||
this._mirrorTrack.removeCue(this._mirrorTrack.cues[0]);
|
||||
for (var captionWindow of captionWindowContainer.querySelectorAll(
|
||||
".caption-window",
|
||||
)) {
|
||||
var text = Array.from(
|
||||
captionWindow.querySelectorAll(".captions-text > span"),
|
||||
)
|
||||
.map((span) => span.textContent)
|
||||
.join("\n");
|
||||
if (!text) continue;
|
||||
var cue = new VTTCue(0, 10e7, text);
|
||||
switch (captionWindow.style.textAlign) {
|
||||
case "left":
|
||||
case "start":
|
||||
cue.align = "start";
|
||||
cue.positionAlign = "line-left";
|
||||
break;
|
||||
case "end":
|
||||
case "right":
|
||||
cue.align = "end";
|
||||
cue.positionAlign = "line-right";
|
||||
break;
|
||||
default:
|
||||
cue.align = "center";
|
||||
cue.positionAlign = "center";
|
||||
}
|
||||
var topPercent = parseFloat(captionWindow.style.top);
|
||||
var bottomPercent = parseFloat(captionWindow.style.bottom);
|
||||
var leftPercent = parseFloat(captionWindow.style.left);
|
||||
var rightPercent = parseFloat(captionWindow.style.right);
|
||||
if (!isNaN(topPercent)) {
|
||||
cue.snapToLines = false;
|
||||
cue.line = topPercent;
|
||||
} else if (!isNaN(bottomPercent)) {
|
||||
cue.snapToLines = false;
|
||||
cue.line = 100 - bottomPercent;
|
||||
}
|
||||
if (!isNaN(leftPercent)) cue.position = leftPercent;
|
||||
else if (!isNaN(rightPercent)) cue.position = 100 - rightPercent;
|
||||
this._mirrorTrack.addCue(cue);
|
||||
}
|
||||
}
|
||||
_attachCaptionWindowObserver() {
|
||||
var container = this._player.querySelector(this._captionWindowSelector);
|
||||
if (container) this._attachCaptionObserver(container);
|
||||
else {
|
||||
this._waitObserver = new MutationObserver(() => {
|
||||
var container = this._player.querySelector(
|
||||
this._captionWindowSelector,
|
||||
);
|
||||
if (container) {
|
||||
this._attachCaptionObserver(container);
|
||||
this._waitObserver.disconnect();
|
||||
this._waitObserver = null;
|
||||
}
|
||||
});
|
||||
this._waitObserver.observe(this._player, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
_attachCaptionObserver(container) {
|
||||
if (this._captionObserver) this._captionObserver.disconnect();
|
||||
this._captionObserver = new MutationObserver(() => {
|
||||
var container = this._player.querySelector(this._captionWindowSelector);
|
||||
if (container) this._syncCues(container);
|
||||
});
|
||||
this._captionObserver.observe(container, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
characterData: true,
|
||||
});
|
||||
}
|
||||
_getIsInline() {
|
||||
if (typeof this._video.webkitPresentationMode === "undefined")
|
||||
return !this._video.webkitDisplayingFullscreen;
|
||||
return this._video.webkitPresentationMode == "inline";
|
||||
}
|
||||
_handlePresentationModeChanged() {
|
||||
var captionContainer = this._player.querySelector(
|
||||
this._captionWindowSelector,
|
||||
);
|
||||
if (this._getIsInline()) {
|
||||
this._mirrorTrack.mode = "hidden";
|
||||
if (captionContainer)
|
||||
captionContainer.style.removeProperty("visibility");
|
||||
return;
|
||||
}
|
||||
this._player.loadModule("captions");
|
||||
this._mirrorTrack.mode = "showing";
|
||||
if (captionContainer)
|
||||
captionContainer.style.setProperty("visibility", "hidden", "important");
|
||||
}
|
||||
_handleMediaSessionAction(details) {
|
||||
switch (details.action) {
|
||||
case "togglecaptions":
|
||||
this._player.toggleSubtitles();
|
||||
break;
|
||||
case "selectcaptiontrack": {
|
||||
var list = this._getTrackList();
|
||||
var index = details.trackIndex;
|
||||
if (index >= 0 && index < list.length)
|
||||
this._player.setOption("captions", "track", list[index]);
|
||||
else this._player.setOption("captions", "track", {});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_getTrackList() {
|
||||
return this._player.getOption("captions", "tracklist") || [];
|
||||
}
|
||||
_getActiveTrack() {
|
||||
return this._player.getOption("captions", "track");
|
||||
}
|
||||
_areTracksEqual(a, b) {
|
||||
return a && b && a.vss_id === b.vss_id;
|
||||
}
|
||||
}
|
||||
window.setupCaptionMirroring = function (video) {
|
||||
new CaptionMirror(video);
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user