* chore: Bump artplayer-plugin-danmuku version to 5.1.0

* chore: Update danmuku plugin with new mount option

* chore: Update danmuku plugin with new mount option

* chore: Update danmuku plugin with new mount option

* chore: Update danmuku plugin with new mount option

* chore: Update danmuku plugin with new mount option

* chore: Update danmuku plugin with new mount option

* chore: Refactor getDanmuTop function to handle additional cases

* chore: Refactor getDanmuTop function to handle additional cases

* chore: Update danmuku plugin with new mount option

* chore: Update danmuku plugin with new mount option

* chore: Refactor danmuku plugin to always create a new Setting instance

* Refactor danmuku plugin to always create a new Setting instance

* Refactor danmuku plugin to always create a new Setting instance

* Update danmuku.js

* Update danmuku.js

* Refactor danmuku plugin to include a new Setting instance

* Refactor danmuku plugin to include a new Setting instance

* Refactor danmuku plugin styles for better alignment and spacing

* Refactor danmuku plugin styles for better alignment and spacing

* Refactor danmuku plugin styles for better alignment and spacing

* Refactor danmuku plugin styles for better alignment and spacing

* Refactor danmuku plugin styles for better alignment and spacing

* chore: Update package.json files

* Refactor danmuku plugin to remove unnecessary whitespace in the setting template

* chore: Remove ESLint configuration files and update npm dependencies

* chore: Update ESLint configuration to disable console warnings and fix unused variable warnings

* chore: Update ESLint configuration to fix quotes rule

* Update package.json

* Update package.json

* Update setting.js

* chore: Compress CSS code in build script

* chore: Update build script to compress JavaScript code

* chore: Update build script to compress JavaScript code

* chore: Refactor setting.js to improve code organization and remove unused variables

* chore: Add isHover flag to Control component for better control hiding behavior

* chore: Update Control component to use $bottom instead of $controls for better control hiding behavior

* Update package.json

* Update package.json

* Update package.json

* chore: Update lerna.json to use independent versioning and yarn as npm client

* refactor: Update Danmuku class to support configurable modes and visibility

* refactor: Update Danmuku styles for better visibility and configurability

* feat: Update font weight in Danmuku styles for better readability

* refactor: Update Danmuku class to support configurable modes and visibility

* refactor: Add opacity, area, font, and speed sliders to Danmuku settings

* refactor: Initialize sliders for opacity, area, font, and speed in Danmuku settings

* feat: Add slider UI for opacity, area, and speed in Danmuku settings

* feat: Update slider styles in Danmuku settings for better visibility and configurability

* refactor: Improve Danmuku settings UI for better visibility and configurability

* refactor: Improve Danmuku settings UI for better visibility and configurability

* refactor: Update slider styles in Danmuku settings for better visibility and configurability

* refactor: Update margin slider initialization in Danmuku settings

* refactor: Update slider styles and initialization in Danmuku settings

* refactor: Update Danmuku class to support configurable visibility

* refactor: Update Danmuku class to support configurable visibility

* refactor: Update Danmuku class to support configurable visibility

* refactor: Update Danmuku class to support configurable visibility

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Improve Danmuku settings UI for better visibility and configurability

* add lock

* refactor: Add lock and unlock methods to Danmuku settings

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* Update artplayer-plugin-danmuku.d.ts

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings event listeners

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability

* refactor: Update Danmuku settings UI for better visibility and configurability
This commit is contained in:
Harvey Zack authored and GitHub committed 2024-05-26 14:57:22 +08:00
1 parent dfd1cf968d
commit 699135afcf
402 files changed
+20804 -17005

No files matched your search

+85 -88
View File
@@ -1,127 +1,125 @@
import SubtitlesOctopus from "libass-wasm"
import SubtitlesOctopus from 'libass-wasm';
const defaultAssSubtitle = `[Script Info]\nScriptType: v4.00+`
const defaultAssSubtitle = `[Script Info]\nScriptType: v4.00+`;
export default class LibassAdapter {
constructor(art, option) {
const { constructor, template } = art
const { constructor, template } = art;
this.art = art
this.$video = template.$video
this.$webvtt = template.$subtitle
this.utils = constructor.utils
this.art = art;
this.$video = template.$video;
this.$webvtt = template.$subtitle;
this.utils = constructor.utils;
this.libass = null
this.libass = null;
art.once("ready", this.init.bind(this, option))
art.once('ready', this.init.bind(this, option));
}
async init(option) {
this.#checkWebAssemblySupport()
this.#checkWebAssemblySupport();
await this.#createLibass(option)
await this.#createLibass(option);
this.#addEventListeners()
this.#addEventListeners();
this.art.emit("artplayerPluginLibass:init", this)
this.art.emit('artplayerPluginLibass:init', this);
// set initial subtitle
const initialSubtitle = this.art?.option?.subtitle?.url
if (initialSubtitle && this.utils.getExt(initialSubtitle) === "ass") {
this.switch(initialSubtitle)
const initialSubtitle = this.art?.option?.subtitle?.url;
if (initialSubtitle && this.utils.getExt(initialSubtitle) === 'ass') {
this.switch(initialSubtitle);
}
}
switch(url) {
this.art.emit("artplayerPluginLibass:switch", url)
this.art.emit('artplayerPluginLibass:switch', url);
if (url && this.utils.getExt(url) === "ass") {
this.currentType = "ass"
this.libass.freeTrack()
this.libass.setTrackByUrl(this.#toAbsoluteUrl(url))
if (url && this.utils.getExt(url) === 'ass') {
this.currentType = 'ass';
this.libass.freeTrack();
this.libass.setTrackByUrl(this.#toAbsoluteUrl(url));
this.visible = this.art.subtitle.show
this.visible = this.art.subtitle.show;
} else {
this.currentType = "webvtt"
this.hide()
this.libass.freeTrack()
this.currentType = 'webvtt';
this.hide();
this.libass.freeTrack();
}
}
setVisibility(visible) {
this.visible = visible
this.visible = visible;
}
setOffset(offset) {
this.timeOffset = offset
this.timeOffset = offset;
}
get active() {
return this.currentType === 'ass'
return this.currentType === 'ass';
}
get visible() {
if (!this.libass)
return false
if (!this.libass) return false;
return this.libass.canvasParent.style.display !== "none"
return this.libass.canvasParent.style.display !== 'none';
}
set visible(visible) {
this.art.emit("artplayerPluginLibass:visible", visible)
this.art.emit('artplayerPluginLibass:visible', visible);
this.#setVttVisible(!this.active)
this.#setVttVisible(!this.active);
if (this.libass.canvasParent) {
this.libass.canvasParent.style.display = visible ? "block" : "none"
this.libass.canvasParent.style.display = visible ? 'block' : 'none';
if (visible) this.libass.resize()
if (visible) this.libass.resize();
}
}
get timeOffset() {
return this.libass.timeOffset
return this.libass.timeOffset;
}
set timeOffset(offset) {
this.art.emit("artplayerPluginLibass:timeOffset", offset)
this.libass.timeOffset = offset
this.art.emit('artplayerPluginLibass:timeOffset', offset);
this.libass.timeOffset = offset;
}
show() {
this.visible = true
this.visible = true;
}
hide() {
this.visible = false
this.visible = false;
}
destroy() {
this.art.emit("artplayerPluginLibass:destroy")
this.art.emit('artplayerPluginLibass:destroy');
this.#removeEventListeners()
this.#removeEventListeners();
this.libass.dispose()
URL.revokeObjectURL(this.workerScriptUrl)
this.libass = null
this.libass.dispose();
URL.revokeObjectURL(this.workerScriptUrl);
this.libass = null;
}
async #createLibass(option = {}) {
if (!option.fallbackFont) {
return this.utils.errorHandle(option.fallbackFont, 'artplayerPluginLibass: fallbackFont is required')
return this.utils.errorHandle(option.fallbackFont, 'artplayerPluginLibass: fallbackFont is required');
}
if (!option.workerUrl) {
option.workerUrl = 'https://cdnjs.cloudflare.com/ajax/libs/libass-wasm/4.1.0/js/subtitles-octopus-worker.js'
option.workerUrl =
'https://cdnjs.cloudflare.com/ajax/libs/libass-wasm/4.1.0/js/subtitles-octopus-worker.js';
}
if (option.availableFonts) {
option.availableFonts = Object
.entries(option.availableFonts)
.reduce((acc, [key, value]) => {
acc[key] = this.#toAbsoluteUrl(value)
return acc
}, {})
option.availableFonts = Object.entries(option.availableFonts).reduce((acc, [key, value]) => {
acc[key] = this.#toAbsoluteUrl(value);
return acc;
}, {});
}
this.libass = new SubtitlesOctopus({
@@ -131,9 +129,9 @@ export default class LibassAdapter {
workerUrl: await this.#loadWorker(option),
fallbackFont: this.#toAbsoluteUrl(option.fallbackFont),
fonts: option.fonts?.map((font) => this.#toAbsoluteUrl(font)),
})
});
this.libass.canvasParent.className = "artplayer-plugin-libass"
this.libass.canvasParent.className = 'artplayer-plugin-libass';
this.libass.canvasParent.style.cssText = `
position: absolute;
top: 0;
@@ -142,81 +140,80 @@ export default class LibassAdapter {
height: 100%;
user-select: none;
pointer-events: none;
z-index: 20;`
z-index: 20;`;
}
#addEventListeners() {
this.switchHandler = this.switch.bind(this)
this.visibleHandler = this.setVisibility.bind(this)
this.offsetHandler = this.setOffset.bind(this)
this.switchHandler = this.switch.bind(this);
this.visibleHandler = this.setVisibility.bind(this);
this.offsetHandler = this.setOffset.bind(this);
this.art.on("subtitle", this.visibleHandler)
this.art.on('subtitleLoad', this.switchHandler)
this.art.on("subtitleOffset", this.offsetHandler)
this.art.on('subtitle', this.visibleHandler);
this.art.on('subtitleLoad', this.switchHandler);
this.art.on('subtitleOffset', this.offsetHandler);
this.art.once("destroy", this.destroy.bind(this))
this.art.once('destroy', this.destroy.bind(this));
}
#removeEventListeners() {
this.art.off("subtitle", this.visibleHandler)
this.art.off('subtitleLoad', this.switchHandler)
this.art.off("subtitleOffset", this.offsetHandler)
this.art.off('subtitle', this.visibleHandler);
this.art.off('subtitleLoad', this.switchHandler);
this.art.off('subtitleOffset', this.offsetHandler);
}
#setVttVisible(visible) {
this.$webvtt.style.visibility = visible ? 'visible' : 'hidden'
this.$webvtt.style.visibility = visible ? 'visible' : 'hidden';
}
#toAbsoluteUrl(url) {
if (this.#isAbsoluteUrl(url))
return url
if (this.#isAbsoluteUrl(url)) return url;
// handle absolute URL when the `Worker` of `BLOB` type loading network resources
return new URL(url, document.baseURI).toString()
return new URL(url, document.baseURI).toString();
}
#isAbsoluteUrl(url) {
return /^https?:\/\//.test(url)
return /^https?:\/\//.test(url);
}
#loadWorker({ workerUrl, wasmUrl }) {
return new Promise((resolve) => {
fetch(workerUrl)
.then(res => res.text())
.then(text => {
let workerScriptContent = text
.then((res) => res.text())
.then((text) => {
let workerScriptContent = text;
workerScriptContent = workerScriptContent.replace(
/wasmBinaryFile\s*=\s*"(subtitles-octopus-worker\.wasm)"/g,
(_match, wasm) => {
if (!wasmUrl) {
wasmUrl = new URL(wasm, workerUrl).toString()
wasmUrl = new URL(wasm, workerUrl).toString();
} else {
wasmUrl = this.#toAbsoluteUrl(wasmUrl)
wasmUrl = this.#toAbsoluteUrl(wasmUrl);
}
return `wasmBinaryFile = "${wasmUrl}"`
}
)
return `wasmBinaryFile = "${wasmUrl}"`;
},
);
const workerBlob = new Blob([workerScriptContent], { type: "text/javascript" })
resolve(URL.createObjectURL(workerBlob))
})
})
const workerBlob = new Blob([workerScriptContent], { type: 'text/javascript' });
resolve(URL.createObjectURL(workerBlob));
});
});
}
#checkWebAssemblySupport() {
let supportsWebAssembly = false
let supportsWebAssembly = false;
try {
if (typeof WebAssembly === "object" && typeof WebAssembly.instantiate === "function") {
const module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00))
if (typeof WebAssembly === 'object' && typeof WebAssembly.instantiate === 'function') {
const module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00));
if (module instanceof WebAssembly.Module)
supportsWebAssembly = (new WebAssembly.Instance(module) instanceof WebAssembly.Instance)
supportsWebAssembly = new WebAssembly.Instance(module) instanceof WebAssembly.Instance;
}
} catch (e) {
//
}
this.utils.errorHandle(supportsWebAssembly, "Browser does not support WebAssembly")
this.utils.errorHandle(supportsWebAssembly, 'Browser does not support WebAssembly');
}
}