Refactor code structure for improved readability and maintainability

feat: add JASSUB type definitions and update common.js references

feat: add JASSUB plugin for advanced subtitle rendering in HTML5 video

- Implemented a new JASSUB class for handling subtitle rendering with options for video and canvas targets.
- Added support for both synchronous and asynchronous rendering modes.
- Integrated Web Worker for offloading rendering tasks, improving performance.
- Included methods for managing subtitle tracks, styles, and events.
- Added color space verification and handling to ensure accurate subtitle display.
- Implemented local font access for enhanced typography options in subtitles.
- Introduced a benchmarking feature to assess rendering performance.

refactor: update README and type definitions for artplayer-plugin-jassub

- Removed installation and usage instructions from README.md for clarity.
- Updated index.js to remove direct assignment of jassub instance to art.
- Enhanced type definitions in artplayer-plugin-jassub.d.ts to include detailed JassubOption and JassubInstance interfaces.
This commit is contained in:
Harvey Zhao committed 2026-01-03 18:56:06 +08:00
1 parent ce35026cb4
commit f4d99eb09e
27 files changed
+8315 -55

No files matched your search

+18 -2
View File
@@ -1,12 +1,28 @@
// https://github.com/ThaUnknown/jassub
// npm i artplayer-plugin-jassub
// import artplayerPluginJassub from 'artplayer-plugin-jassub';
var art = new Artplayer({
container: '.artplayer-app',
url: '/assets/sample/video.mp4',
url: '/assets/jassub/FateGrandOrderBabylonia-OP1v2-NCBD1080.webm',
autoSize: true,
fullscreen: true,
fullscreenWeb: true,
plugins: [
artplayerPluginJassub({
//
subUrl: '/assets/jassub/FGOBD.ass',
workerUrl: '/assets/jassub/jassub-worker.js',
wasmUrl: '/assets/jassub/jassub-worker.wasm',
modernWasmUrl: '/assets/jassub/jassub-worker-modern.wasm',
availableFonts: {
'liberation sans': '/assets/jassub/default.woff2'
},
fonts: [
'/assets/jassub/fonts/Averia Sans Libre Light.ttf',
'/assets/jassub/fonts/Averia Serif Simple Light.ttf',
'/assets/jassub/fonts/Gramond.ttf'
],
timeOffset: -0.041
}),
],
});
File diff suppressed because it is too large. Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
"use strict";async function Module(i={}){var g,v=i,y=(...t)=>console.log(...t),h=(...t)=>console.error(...t);function T(){j?.(v)}G=(t=>()=>{t(),self.wasmMemory=B,self.HEAPU8C=new Uint8ClampedArray(B.buffer),self.HEAPU8=new Uint8Array(B.buffer)})(G);function P(t){throw t}var j,w,C,A,M,E,O,ie,oe,le=!1;function G(){var t=B.buffer;w=new Int8Array(t),A=new Int16Array(t),C=new Uint8Array(t),M=new Uint16Array(t),E=new Int32Array(t),O=new Uint32Array(t),ie=new Float32Array(t),oe=new Float64Array(t)}function $e(){{var t=62914560;B=new WebAssembly.Memory({initial:t/65536,maximum:32768})}G()}$e();var X=t=>Xe(t),Q=()=>Qe(),B,fe=new TextDecoder,Z=(t,r,n,s)=>{var o=r+n;if(s)return o;for(;t[r]&&!(r>=o);)++r;return r},q=(t,r,n)=>{if(!t)return"";var s=Z(C,t,r,n);return fe.decode(C.subarray(t,s))},Ce=(t,r,n,s)=>P(`Assertion failed: ${q(t)}, at: `+[r?q(r):"unknown filename",n,s?q(s):"unknown function"]);function _e(t,r,n){return 0}var we=(t,r,n)=>{};function tr(t,r,n){return 0}function nr(t,r,n,s){}var ar=()=>P(""),sr=(t,r,n,s,o)=>{},U=t=>{for(var r="";;){var n=C[t++];if(!n)return r;r+=String.fromCharCode(n)}},J={},K={},ue={},N=class extends Error{constructor(r){super(r),this.name="BindingError"}},$=t=>{throw new N(t)};function ir(t,r,n={}){var s=r.name;if(t||$(`type "${s}" must have a positive integer typeid pointer`),K.hasOwnProperty(t)){if(n.ignoreDuplicateRegistrations)return;$(`Cannot register type '${s}' twice`)}if(K[t]=r,delete ue[t],J.hasOwnProperty(t)){var o=J[t];delete J[t],o.forEach(l=>l())}}function L(t,r,n={}){return ir(t,r,n)}var or=(t,r,n,s)=>{r=U(r),L(t,{name:r,fromWireType:function(o){return!!o},toWireType:function(o,l){return l?n:s},readValueFromPointer:function(o){return this.fromWireType(C[o])},destructorFunction:null})},lr=t=>({count:t.count,deleteScheduled:t.deleteScheduled,preservePointerOnDelete:t.preservePointerOnDelete,ptr:t.ptr,ptrType:t.ptrType,smartPtr:t.smartPtr,smartPtrType:t.smartPtrType}),Te=t=>{function r(n){return n.$$.ptrType.registeredClass.name}$(r(t)+" instance already deleted")},Pe=!1,Me=t=>{},fr=t=>{t.smartPtr?t.smartPtrType.rawDestructor(t.smartPtr):t.ptrType.registeredClass.rawDestructor(t.ptr)},Re=t=>{t.count.value-=1;var r=t.count.value===0;r&&fr(t)},ee=t=>globalThis.FinalizationRegistry?(Pe=new FinalizationRegistry(r=>{Re(r.$$)}),ee=r=>{var n=r.$$,s=!!n.smartPtr;if(s){var o={$$:n};Pe.register(r,o,r)}return r},Me=r=>Pe.unregister(r),ee(t)):(ee=r=>r,t),ce=[],ur=()=>{for(;ce.length;){var t=ce.pop();t.$$.deleteScheduled=!1,t.delete()}},Ee,cr=()=>{let t=de.prototype;Object.assign(t,{isAliasOf(n){if(!(this instanceof de)||!(n instanceof de))return!1;var s=this.$$.ptrType.registeredClass,o=this.$$.ptr;n.$$=n.$$;for(var l=n.$$.ptrType.registeredClass,u=n.$$.ptr;s.baseClass;)o=s.upcast(o),s=s.baseClass;for(;l.baseClass;)u=l.upcast(u),l=l.baseClass;return s===l&&o===u},clone(){if(this.$$.ptr||Te(this),this.$$.preservePointerOnDelete)return this.$$.count.value+=1,this;var n=ee(Object.create(Object.getPrototypeOf(this),{$$:{value:lr(this.$$)}}));return n.$$.count.value+=1,n.$$.deleteScheduled=!1,n},delete(){this.$$.ptr||Te(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&$("Object already scheduled for deletion"),Me(this),Re(this.$$),this.$$.preservePointerOnDelete||(this.$$.smartPtr=void 0,this.$$.ptr=void 0)},isDeleted(){return!this.$$.ptr},deleteLater(){return this.$$.ptr||Te(this),this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete&&$("Object already scheduled for deletion"),ce.push(this),ce.length===1&&Ee&&Ee(ur),this.$$.deleteScheduled=!0,this}});const r=Symbol.dispose;r&&(t[r]=t.delete)};function de(){}var ke=(t,r)=>Object.defineProperty(r,"name",{value:t}),We={},Ue=(t,r,n)=>{if(t[r].overloadTable===void 0){var s=t[r];t[r]=function(...o){return t[r].overloadTable.hasOwnProperty(o.length)||$(`Function '${n}' called with an invalid number of arguments (${o.length}) - expects one of (${t[r].overloadTable})!`),t[r].overloadTable[o.length].apply(this,o)},t[r].overloadTable=[],t[r].overloadTable[s.argCount]=s}},dr=(t,r,n)=>{v.hasOwnProperty(t)?((n===void 0||v[t].overloadTable!==void 0&&v[t].overloadTable[n]!==void 0)&&$(`Cannot register public name '${t}' twice`),Ue(v,t,t),v[t].overloadTable.hasOwnProperty(n)&&$(`Cannot register multiple overloads of a function with the same number of arguments (${n})!`),v[t].overloadTable[n]=r):(v[t]=r,v[t].argCount=n)},vr=48,pr=57,gr=t=>{t=t.replace(/[^a-zA-Z0-9_]/g,"$");var r=t.charCodeAt(0);return r>=vr&&r<=pr?`_${t}`:t};function br(t,r,n,s,o,l,u,f){this.name=t,this.constructor=r,this.instancePrototype=n,this.rawDestructor=s,this.baseClass=o,this.getActualType=l,this.upcast=u,this.downcast=f,this.pureVirtualFunctions=[]}var ve=(t,r,n)=>{for(;r!==n;)r.upcast||$(`Expected null or instance of ${n.name}, got an instance of ${r.name}`),t=r.upcast(t),r=r.baseClass;return t},je=t=>{if(t===null)return"null";var r=typeof t;return r==="object"||r==="array"||r==="function"?t.toString():""+t};function hr(t,r){if(r===null)return this.isReferencLine truncated
`;o&&(m+=`var destructors = [];
`);var _=o?"destructors":"null",S=["humanName","throwBindingError","invoker","fn","runDestructors","fromRetWire","toClassParamWire"];r&&(m+=`var thisWired = toClassParamWire(${_}, this);
`);for(var p=0;p<l;++p){var R=`toArg${p}Wire`;m+=`var arg${p}Wired = ${R}(${_}, arg${p});
`,S.push(R)}if(m+=(n||s?"var rv = ":"")+`invoker(${f});
`,o)m+=`runDestructors(destructors);
`;else for(var p=r?1:2;p<t.length;++p){var F=p===1?"thisWired":"arg"+(p-2)+"Wired";t[p].destructorFunction!==null&&(m+=`${F}_dtor(${F});
`,S.push(`${F}_dtor`))}return n&&(m+=`var ret = fromRetWire(rv);
return ret;
`),m+=`}
`,new Function(S,m)}function He(t,r,n,s,o,l){var u=r.length;u<2&&$("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var f=r[1]!==null&&n!==null,p=xe(r),m=!r[0].isVoid,_=r[0],S=r[1],R=[t,$,s,o,Le,_.fromWireType.bind(_),S?.toWireType.bind(S)],F=2;F<u;++F){var k=r[F];R.push(k.toWireType.bind(k))}if(!p)for(var F=f?1:2;F<r.length;++F)r[F].destructorFunction!==null&&R.push(r[F].destructorFunction);var x=Er(r,f,m,l)(...R);return ke(t,x)}var kr=(t,r,n,s,o,l)=>{var u=Be(r,n);o=H(s,o),z([],[t],f=>{f=f[0];var p=`constructor ${f.name}`;if(f.registeredClass.constructor_body===void 0&&(f.registeredClass.constructor_body=[]),f.registeredClass.constructor_body[r-1]!==void 0)throw new N(`Cannot register multiple constructors with identical number of parameters (${r-1}) for class '${f.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`);return f.registeredClass.constructor_body[r-1]=()=>{te(`Cannot construct ${f.name} due to unbound types`,u)},z([],u,m=>(m.splice(1,0,null),f.registeredClass.constructor_body[r-1]=He(p,m,null,o,l),[])),[]})},Wr=t=>{t=t.trim();const r=t.indexOf("(");return r===-1?t:t.slice(0,r)},Ur=(t,r,n,s,o,l,u,f,p,m)=>{var _=Be(n,s);r=U(r),r=Wr(r),l=H(o,l,p),z([],[t],S=>{S=S[0];var R=`${S.name}.${r}`;r.startsWith("@@")&&(r=Symbol[r.substring(2)]),f&&S.registeredClass.pureVirtualFunctions.push(r);function F(){te(`Cannot call ${R} due to unbound types`,_)}var k=S.registeredClass.instancePrototype,D=k[r];return D===void 0||D.overloadTable===void 0&&D.className!==S.name&&D.argCount===n-2?(F.argCount=n-2,F.className=S.name,k[r]=F):(Ue(k,r,R),k[r].overloadTable[n-2]=F),z([],_,x=>{var I=He(R,x,S,l,u,p);return k[r].overloadTable===void 0?(I.argCount=n-2,k[r]=I):k[r].overloadTable[n-2]=I,[]}),[]})},Ve=(t,r,n)=>(t instanceof Object||$(`${n} with invalid "this": ${t}`),t instanceof r.registeredClass.constructor||$(`${n} incompatible with "this" of type ${t.constructor.name}`),t.$$.ptr||$(`cannot call emscripten binding method ${n} on deleted object`),ve(t.$$.ptr,t.$$.ptrType.registeredClass,r.registeredClass)),Dr=(t,r,n,s,o,l,u,f,p,m)=>{r=U(r),o=H(s,o),z([],[t],_=>{_=_[0];var S=`${_.name}.${r}`,R={get(){te(`Cannot access ${S} due to unbound types`,[n,u])},enumerable:!0,configurable:!0};return p?R.set=()=>te(`Cannot access ${S} due to unbound types`,[n,u]):R.set=F=>$(S+" is a read-only property"),Object.defineProperty(_.registeredClass.instancePrototype,r,R),z([],p?[n,u]:[n],F=>{var k=F[0],D={get(){var I=Ve(this,_,S+" getter");return k.fromWireType(o(l,I))},enumerable:!0};if(p){p=H(f,p);var x=F[1];D.set=function(I){var se=Ve(this,_,S+" setter"),W=[];p(m,se,x.toWireType(W,I)),Le(W)}}return Object.defineProperty(_.registeredClass.instancePrototype,r,D),[]}),[]})},ze=[],Y=[0,1,,1,null,1,!0,1,!1,1],Ir=t=>{t>9&&--Y[t+1]===0&&(Y[t]=void 0,ze.push(t))},Fe={toValue:t=>(t||$(`Cannot use deleted val. handle = ${t}`),Y[t]),toHandle:t=>{switch(t){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:{const r=ze.pop()||Y.length;return Y[r]=t,Y[r+1]=1,r}}}},Br={name:"emscripten::val",fromWireType:t=>{var r=Fe.toValue(t);return Ir(t),r},toWireType:(t,r)=>Fe.toHandle(r),readValueFromPointer:pe,destructorFunction:null},Lr=t=>L(t,Br),xr=(t,r)=>{switch(r){case 4:return function(n){return this.fromWireType(ie[n>>2])};case 8:return function(n){return this.fromWireType(oe[n>>3])};default:throw new TypeError(`invalid float width (${r}): ${t}`)}},Hr=(t,r,n)=>{r=U(r),L(t,{name:r,fromWireType:s=>s,toWireType:(s,o)=>o,readValueFromPointer:xr(r,n),destructorFunction:null})},Vr=(t,r,n)=>{switch(r){case 1:return n?s=>w[s]:s=>C[s];case 2:return n?s=>A[s>>1]:s=>M[s>>1];case 4:return n?s=>E[s>>2]:s=>O[s>>2];default:throw new TypeError(`invalid integer width (${r}): ${t}`)}},zr=(t,r,n,s,o)=>{r=U(r);const l=s===0;let u=p=>p;if(l){var f=32-8*n;u=p=>p<<f>>>f,o=u(o)}L(t,{name:r,fromWireType:u,toWireType:(p,m)=>m,readValueFromPointer:Vr(r,n,s!==0),destructorFunction:null})},Gr=(t,r,n)=>{var s=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],o=s[r];function l(u){var f=O[u>>2],p=O[u+4>>2];return new o(w.buffer,p,f)}n=U(n),L(t,{name:n,fromWireType:l,readValueFromPointer:l},{ignoreDuplicateRegistrations:!0})},qr=(t,r,n,s)=>{if(!(s>0))return 0;for(var o=n,l=n+s-1,u=0;u<t.length;++u){var f=t.codePointAt(u);if(f<=127){if(n>=l)break;r[n++]=f}else if(f<=2047){if(n+1>=l)break;r[n++]=192|f>>6,r[n++]=128|f&63}else if(f<=65535){if(n+2>=l)break;r[n++]=224|f>>12,r[n++]=128|f>>6&63,r[n++]=128|f&63}else{if(n+3>=l)break;r[n++]=240|f>>18,r[n++]=128|f>>12&63,r[n++]=128|f>>6&63,r[n++]=128|f&63,u++}}return r[n]=0,n-o},Ge=(t,r,n)=>qr(t,C,r,n),qe=t=>{for(var r=0,n=0;n<t.length;++n){var s=t.charCodeAt(n);s<=127?r++:s<=2047?r+=2:s>=55296&&s<=57343?(r+=4,++n):r+=3}return r},Jr=(t,r)=>{r=U(r),L(t,{name:r,fromWireType(n){var s=O[n>>2],o=n+4,l;return l=q(o,s,!0),V(n),l},toWireType(n,s){s instanceof ArrayBuffer&&(s=new Uint8Arr Line truncated
Binary file not shown.
+1
View File
@@ -64,6 +64,7 @@
'./assets/ts/artplayer-plugin-vtt-thumbnail.d.ts',
'./assets/ts/artplayer-plugin-document-pip.d.ts',
'./assets/ts/artplayer-plugin-liquid-glass.d.ts',
'./assets/ts/artplayer-plugin-jassub.d.ts',
'./assets/ts/artplayer-proxy-canvas.d.ts',
'./assets/ts/artplayer-proxy-mediabunny.d.ts',
'./assets/ts/artplayer.d.ts',
+38
View File
@@ -0,0 +1,38 @@
export interface JassubOption {
workerUrl: string
wasmUrl: string
modernWasmUrl: string
subUrl?: string
subContent?: string
timeOffset?: number
debug?: boolean
prescaleFactor?: number
prescaleHeightLimit?: number
maxRenderHeight?: number
fonts?: string[] | Uint8Array[]
availableFonts?: Record<string, Uint8Array | string>
fallbackFont?: string
useLocalFonts?: boolean
libassMemoryLimit?: number
libassGlyphLimit?: number
[key: string]: any
}
export interface JassubInstance {
resize: (force?: boolean, width?: number, height?: number, top?: number, left?: number) => Promise<void>
setVideo: (video: HTMLVideoElement) => Promise<void>
destroy: () => Promise<void>
[key: string]: any
}
interface Result {
name: 'artplayerPluginJassub'
instance: JassubInstance
}
declare const artplayerPluginJassub: (option: JassubOption) => (art: Artplayer) => Result
export default artplayerPluginJassub
export = artplayerPluginJassub
export as namespace artplayerPluginJassub;
-22
View File
@@ -853,28 +853,15 @@ export interface CssVar {
'--art-theme': string
'--art-font-color': string
'--art-background-color': string
'--art-font-size-sm': string
'--art-text-shadow-color': string
'--art-transition-duration': string
'--art-ease-standard': string
'--art-padding': string
'--art-border-radius': string
'--art-mobile-padding': string
'--art-mobile-radius': string
'--art-radius-sm': string
'--art-space-xxs': string
'--art-space-xs': string
'--art-surface-hover-color': string
'--art-surface-border-color': string
'--art-surface-muted-color': string
'--art-surface-range-color': string
'--art-progress-height': string
'--art-progress-color': string
'--art-progress-top-gap': string
'--art-hover-color': string
'--art-loaded-color': string
'--art-tip-padding': string
'--art-tip-offset': string
'--art-state-size': string
'--art-state-opacity': number
'--art-bottom-height': string
@@ -886,7 +873,6 @@ export interface CssVar {
'--art-control-opacity': number
'--art-control-icon-size': string
'--art-control-icon-scale': number
'--art-touch-hit-size': string
'--art-volume-height': string
'--art-volume-handle-size': string
'--art-lock-size': string
@@ -897,7 +883,6 @@ export interface CssVar {
'--art-settings-max-height': string
'--art-selector-max-height': string
'--art-contextmenus-min-width': string
'--art-contextmenu-padding-x': string
'--art-subtitle-font-size': string
'--art-subtitle-gap': string
'--art-subtitle-bottom': string
@@ -908,13 +893,6 @@ export interface CssVar {
'--art-scrollbar-background': string
'--art-scrollbar-background-hover': string
'--art-mini-progress-height': string
'--art-shadow-low': string
'--art-shadow-medium': string
'--art-shadow-high': string
'--art-shadow-elevated': string
'--art-icon-small-size': string
'--art-overlay-dim': string
'--art-overlay-strong': string
}
export interface Config {