Files
ArtPlayer/docs/compiled/artplayer-plugin-vtt-thumbnail.mjs
Harvey Zhao 65e51751cd feat: add danmuku plugin and i18n setup documentation
- Created a new documentation file for the danmuku plugin with code examples.
- Added a new documentation file for language settings (i18n) with detailed instructions on language imports, default languages, and how to add or modify languages.
- Included code snippets for initializing the Artplayer with different language settings.
2026-03-12 22:23:44 +08:00

125 lines
4.2 KiB
JavaScript

/*!
* artplayer-plugin-vtt-thumbnail.js v1.1.0
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-2026 Harvey Zhao
* Released under the MIT License.
*/
function padEnd(str, targetLength, padString) {
if (str.length > targetLength) {
return String(str);
} else {
targetLength = targetLength - str.length;
if (targetLength > padString.length) {
padString += padString.repeat(targetLength / padString.length);
}
return String(str) + padString.slice(0, targetLength);
}
}
function t2d(time) {
const arr = time.split(".");
const left = arr[0].split(":") || [];
const right = padEnd(arr[1] || "0", 3, "0");
const ms = Number(right) / 1e3;
const h = Number(left[left.length - 3] || 0) * 3600;
const m = Number(left[left.length - 2] || 0) * 60;
const s = Number(left[left.length - 1] || 0);
return h + m + s + ms;
}
async function getVttArray(vttUrl = "") {
const vttString = await (await fetch(vttUrl)).text();
const lines = vttString.split(/[\n\r]/g).filter((item) => item.trim());
const vttArray = [];
for (let i = 1; i < lines.length; i += 2) {
const time = lines[i];
const text = lines[i + 1];
if (!text.trim())
continue;
const timeReg = /((?:\d{2}:)?(?:\d{2}:)?\d{2}(?:.\d{3})?) ?--> ?((?:\d{2}:)?(?:\d{2}:)?\d{2}(?:.\d{3})?)/;
const timeMatch = time.match(timeReg);
const textReg = /(.*)#(\w{4})=(.*)/;
const textMatch = text.match(textReg);
const start = Math.floor(t2d(timeMatch[1]));
const end = Math.floor(t2d(timeMatch[2]));
let url = textMatch[1];
const isAbsoluteUrl = /^\/|(?:https?|ftp|file):\/\//i.test(url);
if (!isAbsoluteUrl) {
const urlArr = vttUrl.split("/");
urlArr.pop();
urlArr.push(url);
url = urlArr.join("/");
}
const result = { start, end, url };
const keys = textMatch[2].split("");
const values = textMatch[3].split(",");
for (let j = 0; j < keys.length; j++) {
result[keys[j]] = values[j];
}
vttArray.push(result);
}
return vttArray;
}
function artplayerPluginVttThumbnail(option) {
return async (art) => {
const {
constructor: {
utils: { setStyle, isMobile, addClass }
},
template: { $progress }
} = art;
let timer = null;
const thumbnails = await getVttArray(option.vtt);
function showThumbnails($control, find, width) {
setStyle($control, "backgroundImage", `url(${find.url})`);
setStyle($control, "height", `${find.h}px`);
setStyle($control, "width", `${find.w}px`);
setStyle($control, "backgroundPosition", `-${find.x}px -${find.y}px`);
if (width <= find.w / 2) {
setStyle($control, "left", 0);
} else if (width > $progress.clientWidth - find.w / 2) {
setStyle($control, "left", `${$progress.clientWidth - find.w}px`);
} else {
setStyle($control, "left", `${width - find.w / 2}px`);
}
}
art.controls.add({
name: "vtt-thumbnail",
position: "top",
index: 20,
style: option.style || {},
mounted($control) {
addClass($control, "art-control-thumbnails");
art.on("setBar", async (type, percentage, event) => {
const isMobileDroging = type === "played" && event && isMobile;
if (type === "hover" || isMobileDroging) {
const width = $progress.clientWidth * percentage;
const second = percentage * art.duration;
setStyle($control, "display", "flex");
const find = thumbnails.find((item) => second >= item.start && second <= item.end);
if (!find)
return setStyle($control, "display", "none");
if (width > 0 && width < $progress.clientWidth) {
showThumbnails($control, find, width);
} else {
if (!isMobile) {
setStyle($control, "display", "none");
}
}
if (isMobileDroging) {
clearTimeout(timer);
timer = setTimeout(() => {
setStyle($control, "display", "none");
}, 500);
}
}
});
}
});
return {
name: "artplayerPluginVttThumbnail"
};
};
}
export {
artplayerPluginVttThumbnail as default
};