Skip to content

Commit 2b696f7

Browse files
committed
build: new version
1 parent 6cf37f2 commit 2b696f7

File tree

2 files changed

+121
-120
lines changed

2 files changed

+121
-120
lines changed

dist/vot-min.user.js

+21-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/vot.user.js

+100-99
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
// @match *://*.bilibili.com/*
4848
// @match *://my.mail.ru/*
4949
// @match *://*.bitchute.com/*
50-
// @match *://*.coursera.org/learn/*
50+
// @match *://*.coursera.org/*
5151
// @match *://*.udemy.com/course/*
5252
// @match *://*.tiktok.com/*
5353
// @match *://*.douyin.com/*
@@ -1574,7 +1574,7 @@ class Chaimu {
15741574
defaultDuration: 343,
15751575
minChunkSize: 5295308,
15761576
loggerLevel: 1,
1577-
version: "2.1.7",
1577+
version: "2.1.8",
15781578
});
15791579

15801580
;// ./node_modules/@vot.js/shared/dist/types/logger.js
@@ -5452,8 +5452,7 @@ class PatreonHelper extends BaseHelper {
54525452
class RedditHelper extends BaseHelper {
54535453
API_ORIGIN = "https://www.reddit.com";
54545454
async getContentUrl(videoId) {
5455-
if (!this.service.additionalData ||
5456-
this.service.additionalData !== "old") {
5455+
if (this.service?.additionalData !== "old") {
54575456
return document.querySelector("shreddit-player-2")?.src;
54585457
}
54595458
const playerEl = document.querySelector("[data-hls-url]");
@@ -5855,8 +5854,8 @@ class CoursehunterLikeHelper extends BaseHelper {
58555854
if (courseId !== undefined) {
58565855
return String(courseId);
58575856
}
5858-
const inputEl = document.querySelector('input[name="course_id"]');
5859-
return inputEl ? inputEl.value : undefined;
5857+
return document.querySelector('input[name="course_id"]')
5858+
?.value;
58605859
}
58615860
async getLessonsData(courseId) {
58625861
const lessons = window.lessons;
@@ -6074,46 +6073,69 @@ class SapHelper extends BaseHelper {
60746073
}
60756074
}
60766075

6077-
;// ./node_modules/@vot.js/ext/dist/helpers/linkedin.js
6076+
;// ./node_modules/@vot.js/ext/dist/helpers/videojs.js
60786077

60796078

60806079

6081-
class LinkedinHelper extends BaseHelper {
6080+
class VideoJSHelper extends BaseHelper {
6081+
SUBTITLE_SOURCE = "videojs";
6082+
SUBTITLE_FORMAT = "vtt";
60826083
static getPlayer() {
6083-
const videoEl = document.querySelector(".video-js");
6084-
if (!videoEl) {
6085-
return undefined;
6086-
}
6087-
return videoEl.player;
6084+
return document.querySelector(".video-js")
6085+
?.player;
60886086
}
6089-
async getVideoData(videoId) {
6087+
getVideoDataByPlayer(videoId) {
60906088
try {
6091-
const player = LinkedinHelper.getPlayer();
6089+
const player = VideoJSHelper.getPlayer();
60926090
if (!player) {
60936091
throw new Error(`Video player doesn't have player option, videoId ${videoId}`);
60946092
}
6095-
const { cache_: { sources, duration }, textTracks_: { tracks_ }, } = player;
6096-
const videoUrl = sources.find((source) => source.type === "video/mp4");
6093+
const duration = player.duration();
6094+
const sources = Array.isArray(player.currentSources)
6095+
? player.currentSources
6096+
: player.getCache()?.sources;
6097+
const { tracks_: tracks } = player.textTracks();
6098+
const videoUrl = sources.find((source) => source.type === "video/mp4" || source.type === "video/webm");
60976099
if (!videoUrl) {
60986100
throw new Error(`Failed to find video url for videoID ${videoId}`);
60996101
}
6100-
const url = new URL(videoUrl.src);
6101-
const subtitles = tracks_.map((track) => ({
6102+
const subtitles = tracks
6103+
.filter((track) => track.src)
6104+
.map((track) => ({
61026105
language: normalizeLang(track.language),
6103-
source: "linkedin",
6104-
format: "vtt",
6106+
source: this.SUBTITLE_SOURCE,
6107+
format: this.SUBTITLE_FORMAT,
61056108
url: track.src,
61066109
}));
61076110
return {
6108-
url: proxyMedia(url),
6111+
url: videoUrl.src,
61096112
duration,
61106113
subtitles,
61116114
};
61126115
}
61136116
catch (err) {
6114-
Logger.error("Failed to get linkedin video data", err.message);
6117+
Logger.error("Failed to get videojs video data", err.message);
6118+
return undefined;
6119+
}
6120+
}
6121+
}
6122+
6123+
;// ./node_modules/@vot.js/ext/dist/helpers/linkedin.js
6124+
6125+
6126+
class LinkedinHelper extends VideoJSHelper {
6127+
SUBTITLE_SOURCE = "linkedin";
6128+
async getVideoData(videoId) {
6129+
const data = this.getVideoDataByPlayer(videoId);
6130+
if (!data) {
61156131
return undefined;
61166132
}
6133+
const { url, duration, subtitles } = data;
6134+
return {
6135+
url: proxyMedia(new URL(url)),
6136+
duration,
6137+
subtitles,
6138+
};
61176139
}
61186140
async getVideoId(url) {
61196141
return /\/learning\/(([^/]+)\/([^/]+))/.exec(url.pathname)?.[1];
@@ -6531,23 +6553,12 @@ class VKHelper extends BaseHelper {
65316553
return undefined;
65326554
}
65336555
const videoView = Videoview;
6534-
return videoView.getPlayerObject
6535-
? videoView.getPlayerObject.call(undefined)
6536-
: undefined;
6537-
}
6538-
getDefault(videoId) {
6539-
if (!this.service) {
6540-
return undefined;
6541-
}
6542-
return {
6543-
url: this.service.url + videoId,
6544-
duration: undefined,
6545-
};
6556+
return videoView?.getPlayerObject?.call(undefined);
65466557
}
65476558
async getVideoData(videoId) {
65486559
const player = VKHelper.getPlayer();
65496560
if (!player) {
6550-
return this.getDefault(videoId);
6561+
return this.returnBaseData(videoId);
65516562
}
65526563
try {
65536564
const { description: descriptionHTML, duration, md_title: title, } = player.vars;
@@ -6577,7 +6588,7 @@ class VKHelper extends BaseHelper {
65776588
}
65786589
catch (err) {
65796590
Logger.error(`Failed to get VK video data, because: ${err.message}`);
6580-
return this.getDefault(videoId);
6591+
return this.returnBaseData(videoId);
65816592
}
65826593
}
65836594
async getVideoId(url) {
@@ -7168,8 +7179,9 @@ class UdemyHelper extends BaseHelper {
71687179

71697180

71707181

7171-
class CourseraHelper extends BaseHelper {
7182+
class CourseraHelper extends VideoJSHelper {
71727183
API_ORIGIN = "https://www.coursera.org/api";
7184+
SUBTITLE_SOURCE = "coursera";
71737185
async getCourseData(courseId) {
71747186
try {
71757187
const response = await this.fetch(`${this.API_ORIGIN}/onDemandCourses.v1/${courseId}`);
@@ -7181,74 +7193,75 @@ class CourseraHelper extends BaseHelper {
71817193
return undefined;
71827194
}
71837195
}
7184-
getPlayer() {
7185-
return document.querySelector(".vjs-v8");
7186-
}
7187-
getPlayerData() {
7188-
return this.getPlayer()?.player;
7189-
}
7190-
findVideoUrl(sources) {
7191-
return sources?.find((src) => src.type === "video/mp4")?.src;
7192-
}
7193-
findSubtitleUrl(captions, detectedLanguage) {
7194-
let subtitle = captions?.find((caption) => normalizeLang(caption.srclang) === detectedLanguage);
7195-
if (!subtitle) {
7196-
subtitle =
7197-
captions?.find((caption) => normalizeLang(caption.srclang) === "en") ||
7198-
captions?.[0];
7199-
}
7200-
return subtitle?.src;
7196+
static getPlayer() {
7197+
return super.getPlayer();
72017198
}
72027199
async getVideoData(videoId) {
7203-
const playerData = this.getPlayerData();
7204-
if (!playerData) {
7205-
Logger.error("Failed to find player data");
7200+
const data = this.getVideoDataByPlayer(videoId);
7201+
if (!data) {
72067202
return undefined;
72077203
}
7208-
const { cache_: { duration }, options_: { courseId, tracks, sources }, } = playerData;
7209-
const videoUrl = this.findVideoUrl(sources);
7210-
if (!videoUrl) {
7211-
Logger.error("Failed to find .mp4 video file in sources", sources);
7212-
return undefined;
7204+
const { options_: options } = CourseraHelper.getPlayer() ?? {};
7205+
if (!data.subtitles?.length && options) {
7206+
data.subtitles = options.tracks.map((track) => ({
7207+
url: track.src,
7208+
language: normalizeLang(track.srclang),
7209+
source: this.SUBTITLE_SOURCE,
7210+
format: this.SUBTITLE_FORMAT,
7211+
}));
7212+
}
7213+
const courseId = options?.courseId;
7214+
if (!courseId) {
7215+
return data;
72137216
}
72147217
let courseLang = "en";
72157218
const courseData = await this.getCourseData(courseId);
72167219
if (courseData) {
72177220
const { primaryLanguageCodes: [primaryLangauge], } = courseData;
7218-
courseLang = primaryLangauge ? normalizeLang(primaryLangauge) : "en";
7221+
courseLang = primaryLangauge
7222+
? normalizeLang(primaryLangauge)
7223+
: "en";
72197224
}
72207225
if (!availableLangs.includes(courseLang)) {
72217226
courseLang = "en";
72227227
}
7223-
const subtitleUrl = this.findSubtitleUrl(tracks, courseLang);
7228+
const subtitleItem = data.subtitles.find((subtitle) => subtitle.language === courseLang) ??
7229+
data.subtitles?.[0];
7230+
const subtitleUrl = subtitleItem?.url;
72247231
if (!subtitleUrl) {
7225-
Logger.warn("Failed to find subtitle file in tracks", tracks);
7226-
}
7232+
Logger.warn("Failed to find any subtitle file");
7233+
}
7234+
const { url, duration } = data;
7235+
const translationHelp = subtitleUrl
7236+
? [
7237+
{
7238+
target: "subtitles_file_url",
7239+
targetUrl: subtitleUrl,
7240+
},
7241+
{
7242+
target: "video_file_url",
7243+
targetUrl: url,
7244+
},
7245+
]
7246+
: null;
72277247
return {
72287248
...(subtitleUrl
72297249
? {
72307250
url: this.service?.url + videoId,
7231-
translationHelp: [
7232-
{
7233-
target: "subtitles_file_url",
7234-
targetUrl: subtitleUrl,
7235-
},
7236-
{
7237-
target: "video_file_url",
7238-
targetUrl: videoUrl,
7239-
},
7240-
],
7251+
translationHelp,
72417252
}
72427253
: {
7243-
url: videoUrl,
7244-
translationHelp: null,
7254+
url,
7255+
translationHelp,
72457256
}),
72467257
detectedLanguage: courseLang,
72477258
duration,
72487259
};
72497260
}
72507261
async getVideoId(url) {
7251-
return /learn\/([^/]+)\/lecture\/([^/]+)/.exec(url.pathname)?.[0];
7262+
const matched = /learn\/([^/]+)\/lecture\/([^/]+)/.exec(url.pathname) ??
7263+
/lecture\/([^/]+)\/([^/]+)/.exec(url.pathname);
7264+
return matched?.[0];
72527265
}
72537266
}
72547267

@@ -7265,18 +7278,18 @@ class CloudflareStreamHelper extends BaseHelper {
72657278

72667279

72677280
class DouyinHelper extends BaseHelper {
7268-
getPlayer() {
7281+
static getPlayer() {
72697282
if (typeof player === "undefined") {
72707283
return undefined;
72717284
}
72727285
return player;
72737286
}
72747287
async getVideoData(videoId) {
7275-
const xgPlayer = this.getPlayer();
7288+
const xgPlayer = DouyinHelper.getPlayer();
72767289
if (!xgPlayer) {
72777290
return undefined;
72787291
}
7279-
const { url: sources, duration, lang, isLive: isStream } = xgPlayer.config;
7292+
const { config: { url: sources, duration, lang, isLive: isStream }, } = xgPlayer;
72807293
if (!sources) {
72817294
return undefined;
72827295
}
@@ -7298,11 +7311,7 @@ class DouyinHelper extends BaseHelper {
72987311
if (pathId) {
72997312
return pathId;
73007313
}
7301-
const xgPlayer = this.getPlayer();
7302-
if (!xgPlayer) {
7303-
return undefined;
7304-
}
7305-
return xgPlayer.config.vid;
7314+
return DouyinHelper.getPlayer()?.config.vid;
73067315
}
73077316
}
73087317

@@ -7356,16 +7365,7 @@ class LoomHelper extends BaseHelper {
73567365
return undefined;
73577366
}
73587367
const release = SENTRY_RELEASE;
7359-
return release?.id;
7360-
}
7361-
getDefault(videoId) {
7362-
if (!this.service) {
7363-
return undefined;
7364-
}
7365-
return {
7366-
url: this.service.url + videoId,
7367-
duration: undefined,
7368-
};
7368+
return release.id;
73697369
}
73707370
async getVideoData(videoId) {
73717371
try {
@@ -7407,7 +7407,7 @@ class LoomHelper extends BaseHelper {
74077407
}
74087408
catch (err) {
74097409
Logger.error(`Failed to get Loom video data, because: ${err.message}`);
7410-
return this.getDefault(videoId);
7410+
return this.returnBaseData(videoId);
74117411
}
74127412
}
74137413
async getVideoId(url) {
@@ -7774,6 +7774,7 @@ async function getVideoData(service, opts = {}) {
77747774

77757775

77767776

7777+
77777778
;// ./node_modules/@vot.js/ext/dist/index.js
77787779

77797780

0 commit comments

Comments
 (0)