feat: add danmuku plugin documentation and i18n setup guide

- Created a new documentation file for the danmuku plugin with code examples.
- Added comprehensive language settings documentation, including default languages, import instructions, and examples for adding and modifying languages.
- Updated the i18n documentation to reflect changes in language handling and provide clear examples for users.
This commit is contained in:
Harvey Zhao committed 2026-01-04 15:59:52 +08:00
1 parent c88aa97c0a
commit c655f073ae
60 files changed
+85 -2496

No files matched your search

@@ -1,6 +0,0 @@
node_modules
.DS_Store
.parcel-cache
yarn.lock
package-lock.json
src
@@ -1,11 +0,0 @@
# artplayer-plugin-libass
A powerful ass subtitle renderer [libass-wasm](https://github.com/libass/JavascriptSubtitlesOctopus) for ArtPlayer
## Demo
[https://artplayer.org](https://artplayer.org/?libs=./uncompiled/artplayer-plugin-libass/index.js&example=libass)
## License
MIT © journey-ad
@@ -1,8 +0,0 @@
/*!
* artplayer-plugin-libass.js v1.0.0
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-2026 Harvey Zack
* Released under the MIT License.
*/
!function(e,t,r,s,n,a,i,o){var l="u">typeof globalThis?globalThis:"u">typeof self?self:"u">typeof window?window:"u">typeof global?global:{},c="function"==typeof l[s]&&l[s],d=c.i||{},u=c.cache||{},v="u">typeof module&&"function"==typeof module.require&&module.require.bind(module);function f(t,r){if(!u[t]){if(!e[t]){if(n[t])return n[t];var a="function"==typeof l[s]&&l[s];if(!r&&a)return a(t,!0);if(c)return c(t,!0);if(v&&"string"==typeof t)return v(t);var i=Error("Cannot find module '"+t+"'");throw i.code="MODULE_NOT_FOUND",i}d.resolve=function(r){var s=e[t][1][r];return null!=s?s:r},d.cache={};var o=u[t]=new f.Module(t);e[t][0].call(o.exports,d,o,o.exports,l)}return u[t].exports;function d(e){var t=d.resolve(e);if(!1===t)return{};if(Array.isArray(t)){var r={__esModule:!0};return t.forEach(function(e){var t=e[0],s=e[1],n=e[2]||e[0],a=f(s);"*"===t?Object.keys(a).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:function(){return a[e]}})}):"*"===n?Object.defineProperty(r,t,{enumerable:!0,value:a}):Object.defineProperty(r,t,{enumerable:!0,get:function(){return"default"===n?a.__esModule?a.default:a:a[n]}})}),r}return f(t)}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.require=v,this.exports={}},f.modules=e,f.cache=u,f.parent=c,f.distDir=void 0,f.publicUrl=void 0,f.devServer=void 0,f.i=d,f.register=function(t,r){e[t]=[function(e,t){t.exports=r},{}]},Object.defineProperty(f,"root",{get:function(){return l[s]}}),l[s]=f;for(var h=0;h<t.length;h++)f(t[h]);if(r){var m=f(r);"object"==typeof exports&&"u">typeof module?module.exports=m:"function"==typeof define&&define.amd&&define(function(){return m})}}({"9G2Gn":[function(e,t,r,s){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");n.defineInteropFlag(r),n.export(r,"default",()=>o);var a=e("./adapter"),i=n.interopDefault(a);function o(e){return t=>{let r=new(0,i.default)(t,e);return{name:"artplayerPluginLibass",libass:r.libass,visible:r.visible,init:r.init.bind(r),switch:r.switch.bind(r),show:r.show.bind(r),hide:r.hide.bind(r),destroy:r.destroy.bind(r)}}}"u">typeof window&&(window.artplayerPluginLibass=o)},{"./adapter":"aO4ju","@parcel/transformer-js/src/esmodule-helpers.js":"6ykb1"}],aO4ju:[function(e,t,r,s){var n=e("@parcel/transformer-js/src/esmodule-helpers.js");n.defineInteropFlag(r);var a=e("libass-wasm"),i=n.interopDefault(a);let o=`[Script Info] ScriptType: v4.00+`;r.default=class{constructor(e,t){const{constructor:r,template:s}=e;this.art=e,this.$video=s.$video,this.$webvtt=s.$subtitle,this.utils=r.utils,this.libass=null,e.once("ready",this.init.bind(this,t))}async init(e){this.#e(),await this.#t(e),this.#r(),this.art.emit("artplayerPluginLibass:init",this);let t=this.art?.option?.subtitle?.url;t&&"ass"===this.utils.getExt(t)&&this.switch(t)}switch(e){this.art.emit("artplayerPluginLibass:switch",e),e&&"ass"===this.utils.getExt(e)?(this.currentType="ass",this.libass.freeTrack(),this.libass.setTrackByUrl(this.#s(e)),this.visible=this.art.subtitle.show):(this.currentType="webvtt",this.hide(),this.libass.freeTrack())}setVisibility(e){this.visible=e}setOffset(e){this.timeOffset=e}get active(){return"ass"===this.currentType}get visible(){return!!this.libass&&"none"!==this.libass.canvasParent.style.display}set visible(e){this.art.emit("artplayerPluginLibass:visible",e),this.#n(!this.active),this.libass.canvasParent&&(this.libass.canvasParent.style.display=e?"block":"none",e&&this.libass.resize())}get timeOffset(){return this.libass.timeOffset}set timeOffset(e){this.art.emit("artplayerPluginLibass:timeOffset",e),this.libass.timeOffset=e}show(){this.visible=!0}hide(){this.visible=!1}destroy(){this.art.emit("artplayerPluginLibass:destroy"),this.#a(),this.libass.dispose(),URL.revokeObjectURL(this.workerScriptUrl),this.libass=null}async #t(e={}){if(!e.fallbackFont)return this.utils.errorHandle(e.fallbackFont,"artplayerPluginLibass: fallbackFont is required");e.workerUrl||(e.workerUrl="https://cdnjs.cloudflare.com/ajax/libs/libass-wasm/4.1.0/js/subtitles-octopus-worker.js"),e.availableFonts&&(e.availableFonts=Object.entries(e.availableFonts).reduce((e,[t,r])=>(e[t]=this.#s(r),e),{})),this.libass=new(0,i.default)({subContent:o,video:this.$video,...e,workerUrl:await this.#i(e),fallbackFont:this.#s(e.fallbackFont),fonts:e.fonts?.map(e=>this.#s(e))}),this.libass.canvasParent.className="artplayer-plugin-libass",this.libass.canvasParent.style.cssText=` position: absolute; top: 0; left: 0; width: 100%; height: 100%; user-select: none; pointer-events: none; z-index: 20;`}#r(){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.once("destroy",this.destroy.bind(this))}#a(){this.art.off("subtitle",this.visibleHandler),this.art.off("subtLine truncated
@@ -1,8 +0,0 @@
/*!
* artplayer-plugin-libass.js v1.0.0
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-2026 Harvey Zack
* Released under the MIT License.
*/
!function(e,t,r,n,s,i,a,o){var c="u">typeof globalThis?globalThis:"u">typeof self?self:"u">typeof window?window:"u">typeof global?global:{},l="function"==typeof c[n]&&c[n],u=l.i||{},d=l.cache||{},f="u">typeof module&&"function"==typeof module.require&&module.require.bind(module);function h(t,r){if(!d[t]){if(!e[t]){if(s[t])return s[t];var i="function"==typeof c[n]&&c[n];if(!r&&i)return i(t,!0);if(l)return l(t,!0);if(f&&"string"==typeof t)return f(t);var a=Error("Cannot find module '"+t+"'");throw a.code="MODULE_NOT_FOUND",a}u.resolve=function(r){var n=e[t][1][r];return null!=n?n:r},u.cache={};var o=d[t]=new h.Module(t);e[t][0].call(o.exports,u,o,o.exports,c)}return d[t].exports;function u(e){var t=u.resolve(e);if(!1===t)return{};if(Array.isArray(t)){var r={__esModule:!0};return t.forEach(function(e){var t=e[0],n=e[1],s=e[2]||e[0],i=h(n);"*"===t?Object.keys(i).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:function(){return i[e]}})}):"*"===s?Object.defineProperty(r,t,{enumerable:!0,value:i}):Object.defineProperty(r,t,{enumerable:!0,get:function(){return"default"===s?i.__esModule?i.default:i:i[s]}})}),r}return h(t)}}h.isParcelRequire=!0,h.Module=function(e){this.id=e,this.bundle=h,this.require=f,this.exports={}},h.modules=e,h.cache=d,h.parent=l,h.distDir=void 0,h.publicUrl=void 0,h.devServer=void 0,h.i=u,h.register=function(t,r){e[t]=[function(e,t){t.exports=r},{}]},Object.defineProperty(h,"root",{get:function(){return c[n]}}),c[n]=h;for(var v=0;v<t.length;v++)h(t[v]);if(r){var p=h(r);"object"==typeof exports&&"u">typeof module?module.exports=p:"function"==typeof define&&define.amd&&define(function(){return p})}}({"4kqKD":[function(e,t,r,n){var s=e("@parcel/transformer-js/src/esmodule-helpers.js");s.defineInteropFlag(r),s.export(r,"default",function(){return o});var i=e("./adapter"),a=s.interopDefault(i);function o(e){return function(t){var r=new(0,a.default)(t,e);return{name:"artplayerPluginLibass",libass:r.libass,visible:r.visible,init:r.init.bind(r),switch:r.switch.bind(r),show:r.show.bind(r),hide:r.hide.bind(r),destroy:r.destroy.bind(r)}}}"u">typeof window&&(window.artplayerPluginLibass=o)},{"./adapter":"jEGLL","@parcel/transformer-js/src/esmodule-helpers.js":"qpMMf"}],jEGLL:[function(e,t,r,n){var s=e("@parcel/transformer-js/src/esmodule-helpers.js");s.defineInteropFlag(r),s.export(r,"default",function(){return L});var i=e("@swc/helpers/cjs/_async_to_generator.cjs"),a=e("@swc/helpers/cjs/_class_call_check.cjs"),o=e("@swc/helpers/cjs/_class_private_method_get.cjs"),c=e("@swc/helpers/cjs/_class_private_method_init.cjs"),l=e("@swc/helpers/cjs/_create_class.cjs"),u=e("@swc/helpers/cjs/_object_spread.cjs"),d=e("@swc/helpers/cjs/_object_spread_props.cjs"),f=e("@swc/helpers/cjs/_sliced_to_array.cjs"),h=e("@swc/helpers/cjs/_type_of.cjs"),v=e("@swc/helpers/cjs/_ts_generator.cjs"),p=e("libass-wasm"),b=s.interopDefault(p),m=new WeakSet,y=new WeakSet,w=new WeakSet,g=new WeakSet,k=new WeakSet,_=new WeakSet,j=new WeakSet,E=new WeakSet,L=function(){"use strict";function e(t,r){(0,a._)(this,e),(0,c._)(this,m),(0,c._)(this,y),(0,c._)(this,w),(0,c._)(this,g),(0,c._)(this,k),(0,c._)(this,_),(0,c._)(this,j),(0,c._)(this,E);var n=t.constructor,s=t.template;this.art=t,this.$video=s.$video,this.$webvtt=s.$subtitle,this.utils=n.utils,this.libass=null,t.once("ready",this.init.bind(this,r))}return(0,l._)(e,[{key:"init",value:function(e){return(0,i._)(function(){var t,r,n,s;return(0,v._)(this,function(i){switch(i.label){case 0:return(0,o._)(this,E,C).call(this),[4,(0,o._)(this,m,O).call(this,e)];case 1:return i.sent(),(0,o._)(this,y,M).call(this),this.art.emit("artplayerPluginLibass:init",this),(s=null==(n=this.art)||null==(r=n.option)||null==(t=r.subtitle)?void 0:t.url)&&"ass"===this.utils.getExt(s)&&this.switch(s),[2]}})}).call(this)}},{key:"switch",value:function(e){this.art.emit("artplayerPluginLibass:switch",e),e&&"ass"===this.utils.getExt(e)?(this.currentType="ass",this.libass.freeTrack(),this.libass.setTrackByUrl((0,o._)(this,k,P).call(this,e)),this.visible=this.art.subtitle.show):(this.currentType="webvtt",this.hide(),this.libass.freeTrack())}},{key:"setVisibility",value:function(e){this.visible=e}},{key:"setOffset",value:function(e){this.timeOffset=e}},{key:"active",get:function(){return"ass"===this.currentType}},{key:"visible",get:function(){return!!this.libass&&"none"!==this.libass.canvasParent.style.display},set:function(e){this.art.emit("artplayerPluginLibass:visible",e),(0,o._)(this,g,T).call(this,!this.active),this.libass.canvasParent&&(this.libass.canvasParent.style.display=e?"block":"none",e&&this.libass.resize())}},{key:"timeOffset",get:function(){return this.libass.timeOffset},set:function(e){this.art.emit("artplayerPluginLibass:timeOffset",e),this.libass.timeOffset=e}},{key:"show",value:function(){this.visible=!0}},{key:"hide",value:function(){this.visible=!1}},{key:"destroy",value:function(){this.art.emit("artplayerPluLine truncated
@@ -1,8 +0,0 @@
/*!
* artplayer-plugin-libass.js v1.0.0
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-2026 Harvey Zack
* Released under the MIT License.
*/
!function(e,t,r,s,a,i,n,o){var l="u">typeof globalThis?globalThis:"u">typeof self?self:"u">typeof window?window:"u">typeof global?global:{},c="function"==typeof l[s]&&l[s],d=c.i||{},u=c.cache||{},v="u">typeof module&&"function"==typeof module.require&&module.require.bind(module);function f(t,r){if(!u[t]){if(!e[t]){if(a[t])return a[t];var i="function"==typeof l[s]&&l[s];if(!r&&i)return i(t,!0);if(c)return c(t,!0);if(v&&"string"==typeof t)return v(t);var n=Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}d.resolve=function(r){var s=e[t][1][r];return null!=s?s:r},d.cache={};var o=u[t]=new f.Module(t);e[t][0].call(o.exports,d,o,o.exports,l)}return u[t].exports;function d(e){var t=d.resolve(e);if(!1===t)return{};if(Array.isArray(t)){var r={__esModule:!0};return t.forEach(function(e){var t=e[0],s=e[1],a=e[2]||e[0],i=f(s);"*"===t?Object.keys(i).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(r,e)||Object.defineProperty(r,e,{enumerable:!0,get:function(){return i[e]}})}):"*"===a?Object.defineProperty(r,t,{enumerable:!0,value:i}):Object.defineProperty(r,t,{enumerable:!0,get:function(){return"default"===a?i.__esModule?i.default:i:i[a]}})}),r}return f(t)}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.require=v,this.exports={}},f.modules=e,f.cache=u,f.parent=c,f.distDir=void 0,f.publicUrl=void 0,f.devServer=void 0,f.i=d,f.register=function(t,r){e[t]=[function(e,t){t.exports=r},{}]},Object.defineProperty(f,"root",{get:function(){return l[s]}}),l[s]=f;for(var h=0;h<t.length;h++)f(t[h]);if(r){var m=f(r);"object"==typeof exports&&"u">typeof module?module.exports=m:"function"==typeof define&&define.amd&&define(function(){return m})}}({hSedR:[function(e,t,r,s){var a=e("@parcel/transformer-js/src/esmodule-helpers.js");a.defineInteropFlag(r),a.export(r,"default",()=>o);var i=e("./adapter"),n=a.interopDefault(i);function o(e){return t=>{let r=new(0,n.default)(t,e);return{name:"artplayerPluginLibass",libass:r.libass,visible:r.visible,init:r.init.bind(r),switch:r.switch.bind(r),show:r.show.bind(r),hide:r.hide.bind(r),destroy:r.destroy.bind(r)}}}"u">typeof window&&(window.artplayerPluginLibass=o)},{"./adapter":"ba6AI","@parcel/transformer-js/src/esmodule-helpers.js":"loqXi"}],ba6AI:[function(e,t,r,s){var a=e("@parcel/transformer-js/src/esmodule-helpers.js");a.defineInteropFlag(r);var i=e("libass-wasm"),n=a.interopDefault(i);let o=`[Script Info] ScriptType: v4.00+`;r.default=class{constructor(e,t){let{constructor:r,template:s}=e;this.art=e,this.$video=s.$video,this.$webvtt=s.$subtitle,this.utils=r.utils,this.libass=null,e.once("ready",this.init.bind(this,t))}async init(e){this.#e(),await this.#t(e),this.#r(),this.art.emit("artplayerPluginLibass:init",this);let t=this.art?.option?.subtitle?.url;t&&"ass"===this.utils.getExt(t)&&this.switch(t)}switch(e){this.art.emit("artplayerPluginLibass:switch",e),e&&"ass"===this.utils.getExt(e)?(this.currentType="ass",this.libass.freeTrack(),this.libass.setTrackByUrl(this.#s(e)),this.visible=this.art.subtitle.show):(this.currentType="webvtt",this.hide(),this.libass.freeTrack())}setVisibility(e){this.visible=e}setOffset(e){this.timeOffset=e}get active(){return"ass"===this.currentType}get visible(){return!!this.libass&&"none"!==this.libass.canvasParent.style.display}set visible(e){this.art.emit("artplayerPluginLibass:visible",e),this.#a(!this.active),this.libass.canvasParent&&(this.libass.canvasParent.style.display=e?"block":"none",e&&this.libass.resize())}get timeOffset(){return this.libass.timeOffset}set timeOffset(e){this.art.emit("artplayerPluginLibass:timeOffset",e),this.libass.timeOffset=e}show(){this.visible=!0}hide(){this.visible=!1}destroy(){this.art.emit("artplayerPluginLibass:destroy"),this.#i(),this.libass.dispose(),URL.revokeObjectURL(this.workerScriptUrl),this.libass=null}async #t(e={}){if(!e.fallbackFont)return this.utils.errorHandle(e.fallbackFont,"artplayerPluginLibass: fallbackFont is required");e.workerUrl||(e.workerUrl="https://cdnjs.cloudflare.com/ajax/libs/libass-wasm/4.1.0/js/subtitles-octopus-worker.js"),e.availableFonts&&(e.availableFonts=Object.entries(e.availableFonts).reduce((e,[t,r])=>(e[t]=this.#s(r),e),{})),this.libass=new(0,n.default)({subContent:o,video:this.$video,...e,workerUrl:await this.#n(e),fallbackFont:this.#s(e.fallbackFont),fonts:e.fonts?.map(e=>this.#s(e))}),this.libass.canvasParent.className="artplayer-plugin-libass",this.libass.canvasParent.style.cssText=` position: absolute; top: 0; left: 0; width: 100%; height: 100%; user-select: none; pointer-events: none; z-index: 20;`}#r(){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.once("destroy",this.destroy.bind(this))}#i(){this.art.off("subtitle",this.visibleHandler),this.art.off("subtitleLine truncated
@@ -1,43 +0,0 @@
{
"name": "artplayer-plugin-libass",
"version": "1.0.0",
"description": "A powerful ass subtitle renderer `libass-wasm` for ArtPlayer",
"author": "Harvey Zack <laozhaochaguan@gmail.com>",
"license": "MIT",
"homepage": "https://artplayer.org",
"repository": {
"type": "git",
"url": "git+https://github.com/zhw2590582/ArtPlayer.git"
},
"bugs": {
"url": "https://github.com/zhw2590582/ArtPlayer/issues"
},
"keywords": [
"html5",
"video",
"player"
],
"exports": {
".": {
"types": "./types/artplayer-plugin-libass.d.ts",
"import": "./dist/artplayer-plugin-libass.mjs",
"require": "./dist/artplayer-plugin-libass.js"
},
"./legacy": {
"types": "./types/artplayer-plugin-libass.d.ts",
"import": "./dist/artplayer-plugin-libass.legacy.js",
"require": "./dist/artplayer-plugin-libass.legacy.js"
}
},
"main": "./dist/artplayer-plugin-libass.js",
"module": "./dist/artplayer-plugin-libass.mjs",
"types": "./types/artplayer-plugin-libass.d.ts",
"legacy": "./dist/artplayer-plugin-libass.legacy.js",
"browserslist": "last 1 Chrome version",
"dependencies": {
"libass-wasm": "^4.1.0"
},
"devDependencies": {
"@hrgui/libass-wasm-ts": "^1.0.3"
}
}
@@ -1,226 +0,0 @@
import SubtitlesOctopus from 'libass-wasm'
const defaultAssSubtitle = `[Script Info]\nScriptType: v4.00+`
export default class LibassAdapter {
constructor(art, option) {
const { constructor, template } = art
this.art = art
this.$video = template.$video
this.$webvtt = template.$subtitle
this.utils = constructor.utils
this.libass = null
art.once('ready', this.init.bind(this, option))
}
async init(option) {
this.#checkWebAssemblySupport()
await this.#createLibass(option)
this.#addEventListeners()
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)
}
}
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))
this.visible = this.art.subtitle.show
}
else {
this.currentType = 'webvtt'
this.hide()
this.libass.freeTrack()
}
}
setVisibility(visible) {
this.visible = visible
}
setOffset(offset) {
this.timeOffset = offset
}
get active() {
return this.currentType === 'ass'
}
get visible() {
if (!this.libass)
return false
return this.libass.canvasParent.style.display !== 'none'
}
set visible(visible) {
this.art.emit('artplayerPluginLibass:visible', visible)
this.#setVttVisible(!this.active)
if (this.libass.canvasParent) {
this.libass.canvasParent.style.display = visible ? 'block' : 'none'
if (visible)
this.libass.resize()
}
}
get timeOffset() {
return this.libass.timeOffset
}
set timeOffset(offset) {
this.art.emit('artplayerPluginLibass:timeOffset', offset)
this.libass.timeOffset = offset
}
show() {
this.visible = true
}
hide() {
this.visible = false
}
destroy() {
this.art.emit('artplayerPluginLibass:destroy')
this.#removeEventListeners()
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')
}
if (!option.workerUrl) {
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
}, {})
}
this.libass = new SubtitlesOctopus({
subContent: defaultAssSubtitle,
video: this.$video,
...option,
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.style.cssText = `
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
user-select: none;
pointer-events: none;
z-index: 20;`
}
#addEventListeners() {
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.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)
}
#setVttVisible(visible) {
this.$webvtt.style.visibility = visible ? 'visible' : 'hidden'
}
#toAbsoluteUrl(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()
}
#isAbsoluteUrl(url) {
return /^https?:\/\//.test(url)
}
#loadWorker({ workerUrl, wasmUrl }) {
return new Promise((resolve) => {
fetch(workerUrl)
.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()
}
else {
wasmUrl = this.#toAbsoluteUrl(wasmUrl)
}
return `wasmBinaryFile = "${wasmUrl}"`
},
)
const workerBlob = new Blob([workerScriptContent], { type: 'text/javascript' })
resolve(URL.createObjectURL(workerBlob))
})
})
}
#checkWebAssemblySupport() {
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 (module instanceof WebAssembly.Module)
supportsWebAssembly = new WebAssembly.Instance(module) instanceof WebAssembly.Instance
}
}
catch (error) {
console.error('WebAssembly is not supported in this browser.', error)
supportsWebAssembly = false
}
this.utils.errorHandle(supportsWebAssembly, 'Browser does not support WebAssembly')
}
}
@@ -1,21 +0,0 @@
import LibassAdapter from './adapter'
export default function artplayerPluginLibass(option) {
return (art) => {
const adapter = new LibassAdapter(art, option)
return {
name: 'artplayerPluginLibass',
libass: adapter.libass,
visible: adapter.visible,
init: adapter.init.bind(adapter),
switch: adapter.switch.bind(adapter),
show: adapter.show.bind(adapter),
hide: adapter.hide.bind(adapter),
destroy: adapter.destroy.bind(adapter),
}
}
}
if (typeof window !== 'undefined') {
window.artplayerPluginLibass = artplayerPluginLibass
}
@@ -1,16 +0,0 @@
import type SubtitlesOctopus from '@hrgui/libass-wasm-ts'
import type Artplayer from 'artplayer'
import type { Options } from 'libass-wasm'
declare const artplayerPluginAss: (options: Options) => (art: Artplayer) => {
name: 'artplayerPluginLibass'
libass: SubtitlesOctopus
visible: boolean
init: () => void
switch: (url: string) => void
show: () => void
hide: () => void
destroy: () => void
}
export default artplayerPluginAss
@@ -72,7 +72,6 @@ const config = {
{ text: 'DASH 控制', link: 'https://artplayer.org/?libs=https://cdnjs.cloudflare.com/ajax/libs/dashjs/4.5.2/dash.all.min.js%0A./uncompiled/artplayer-plugin-dash-control/index.js&example=dash.control' },
{ text: 'VTT 缩略图', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vtt-thumbnail/index.js&example=vtt.thumbnail' },
{ text: '多重字幕', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-multiple-subtitles/index.js&example=multiple.subtitles' },
{ text: 'ASS 字幕 - JSSO', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-libass/index.js&example=libass' },
{ text: 'ASS 字幕 - JASSUB', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-jassub/index.js&example=jassub' },
{ text: 'Chromecast', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-chromecast/index.js&example=chromecast' },
{ text: 'VAST 广告', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vast/index.js&example=vast' },
@@ -144,7 +143,6 @@ const config = {
{ text: 'DASH Control', link: 'https://artplayer.org/?libs=https://cdnjs.cloudflare.com/ajax/libs/dashjs/4.5.2/dash.all.min.js%0A./uncompiled/artplayer-plugin-dash-control/index.js&example=dash.control' },
{ text: 'VTT Thumbnail', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vtt-thumbnail/index.js&example=vtt.thumbnail' },
{ text: 'Multiple Subtitles', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-multiple-subtitles/index.js&example=multiple.subtitles' },
{ text: 'ASS Subtitle - JSSO', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-libass/index.js&example=libass' },
{ text: 'ASS Subtitle - JASSUB', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-jassub/index.js&example=jassub' },
{ text: 'Chromecast', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-chromecast/index.js&example=chromecast' },
{ text: 'VAST', link: 'https://artplayer.org/?libs=./uncompiled/artplayer-plugin-vast/index.js&example=vast' },