akarisub 0.2.2 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +198 -167
  2. package/THIRD_PARTY_NOTICES.md +55 -163
  3. package/dist/COPYRIGHT +56 -164
  4. package/dist/index.d.ts +26 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +24 -147
  7. package/dist/index.js.map +1 -0
  8. package/dist/ts/akarisub.d.ts +323 -0
  9. package/dist/ts/akarisub.d.ts.map +1 -0
  10. package/dist/ts/akarisub.js +2235 -0
  11. package/dist/ts/akarisub.js.map +1 -0
  12. package/dist/ts/timing.d.ts +63 -0
  13. package/dist/ts/timing.d.ts.map +1 -0
  14. package/dist/ts/timing.js +219 -0
  15. package/dist/ts/timing.js.map +1 -0
  16. package/dist/ts/{ts/types.d.ts → types.d.ts} +176 -78
  17. package/dist/ts/types.d.ts.map +1 -0
  18. package/dist/ts/types.js +2 -0
  19. package/dist/ts/{ts/types.js.map → types.js.map} +1 -1
  20. package/dist/ts/{ts/utils.d.ts → utils.d.ts} +24 -37
  21. package/dist/ts/utils.d.ts.map +1 -0
  22. package/dist/ts/{ts/utils.js → utils.js} +12 -56
  23. package/dist/ts/utils.js.map +1 -0
  24. package/dist/ts/wasm.d.ts +12 -0
  25. package/dist/ts/wasm.d.ts.map +1 -0
  26. package/dist/ts/wasm.js +46 -0
  27. package/dist/ts/wasm.js.map +1 -0
  28. package/dist/ts/{ts/webgl2-renderer.d.ts → webgl2-renderer.d.ts} +17 -12
  29. package/dist/ts/webgl2-renderer.d.ts.map +1 -0
  30. package/dist/ts/{ts/webgl2-renderer.js → webgl2-renderer.js} +17 -27
  31. package/dist/ts/webgl2-renderer.js.map +1 -0
  32. package/dist/ts/webgpu-renderer.d.ts +88 -0
  33. package/dist/ts/webgpu-renderer.d.ts.map +1 -0
  34. package/dist/ts/{ts/webgpu-renderer.js → webgpu-renderer.js} +173 -71
  35. package/dist/ts/webgpu-renderer.js.map +1 -0
  36. package/dist/ts/worker.d.ts +2 -0
  37. package/dist/ts/{ts/worker.d.ts.map → worker.d.ts.map} +1 -1
  38. package/dist/ts/{ts/worker.js → worker.js} +1064 -264
  39. package/dist/ts/worker.js.map +1 -0
  40. package/dist/wrapper.d.ts +8 -0
  41. package/dist/wrapper.d.ts.map +1 -0
  42. package/dist/{ts/index.js → wrapper.js} +4 -14
  43. package/dist/wrapper.js.map +1 -0
  44. package/package.json +24 -22
  45. package/pkg/akarisub.js +53 -0
  46. package/{dist/akarisub-worker.wasm → pkg/akarisub.wasm} +0 -0
  47. package/src/wrapper.ts +46 -0
  48. package/dist/akarisub-worker.js +0 -39
  49. package/dist/akarisub.umd.js +0 -159
  50. package/dist/ts/index.d.ts +0 -14
  51. package/dist/ts/index.d.ts.map +0 -1
  52. package/dist/ts/index.js.map +0 -1
  53. package/dist/ts/ts/akarisub.d.ts +0 -225
  54. package/dist/ts/ts/akarisub.d.ts.map +0 -1
  55. package/dist/ts/ts/akarisub.js +0 -1073
  56. package/dist/ts/ts/akarisub.js.map +0 -1
  57. package/dist/ts/ts/types.d.ts.map +0 -1
  58. package/dist/ts/ts/types.js +0 -5
  59. package/dist/ts/ts/utils.d.ts.map +0 -1
  60. package/dist/ts/ts/utils.js.map +0 -1
  61. package/dist/ts/ts/webgl2-renderer.d.ts.map +0 -1
  62. package/dist/ts/ts/webgl2-renderer.js.map +0 -1
  63. package/dist/ts/ts/webgpu-renderer.d.ts +0 -62
  64. package/dist/ts/ts/webgpu-renderer.d.ts.map +0 -1
  65. package/dist/ts/ts/webgpu-renderer.js.map +0 -1
  66. package/dist/ts/ts/worker.d.ts +0 -6
  67. package/dist/ts/ts/worker.js.map +0 -1
  68. package/dist/ts/wrapper.d.ts +0 -8
  69. package/dist/ts/wrapper.d.ts.map +0 -1
  70. package/dist/ts/wrapper.js +0 -9
  71. package/dist/ts/wrapper.js.map +0 -1
  72. package/src/ts/akarisub.ts +0 -1272
  73. package/src/ts/types.ts +0 -397
  74. package/src/ts/utils.ts +0 -512
  75. package/src/ts/webgl2-renderer.ts +0 -426
  76. package/src/ts/webgpu-renderer.ts +0 -691
  77. package/src/ts/worker.ts +0 -2052
  78. /package/{dist → assets}/default.woff2 +0 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * AkariSub — ASS/SSA subtitle renderer for the browser.
3
+ *
4
+ * Renders libass subtitles with a WebAssembly worker and an optional WebGPU or
5
+ * WebGL2 compositor.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import AkariSub from '@altq/akarisub'
10
+ *
11
+ * const renderer = new AkariSub({
12
+ * video: document.querySelector('video')!,
13
+ * subUrl: '/subtitles/example.ass'
14
+ * })
15
+ *
16
+ * renderer.destroy()
17
+ * ```
18
+ *
19
+ * @module
20
+ */
21
+ export { default } from './wrapper';
22
+ export { default as AkariSub } from './wrapper';
23
+ export type { ASSEvent, ASSStyle, AkariSubOptions, FrameTimeline, PerformanceStats, ASSEventCallback, ASSStyleCallback, PerformanceStatsCallback, ResetStatsCallback, RenderImage, RenderTimes, VideoFrameCallbackMetadata, SubtitleColorSpace, WebYCbCrColorSpace, EncryptedSubtitleContent } from './ts/types';
24
+ export type { ASSSection, ASSBodyEntry } from './ts/utils';
25
+ export { webYCbCrMap, colorMatrixConversionMap, libassYCbCrMap, computeCanvasSize, getVideoPosition, fixAlpha, parseAss, dropBlur, fixPlayRes, testImageBugs, runFeatureTests, getAlphaBug, getBitmapBug, getColorSpaceFilterUrl, getWasmUrl, getWasmGlueUrl, getDefaultFontUrl, WebGPURenderer, isWebGPUSupported, WebGL2Renderer, isWebGL2Supported } from './wrapper';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,WAAW,CAAA;AAE/C,YAAY,EACV,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,WAAW,EACX,WAAW,EACX,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,YAAY,CAAA;AAEnB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE1D,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EAClB,MAAM,WAAW,CAAA"}
package/dist/index.js CHANGED
@@ -1,147 +1,24 @@
1
- var u={bt709:"BT709",bt470bg:"BT601",smpte170m:"BT601"},y={BT601:{BT709:"1.0863 -0.0723 -0.014 0 0 0.0965 0.8451 0.0584 0 0 -0.0141 -0.0277 1.0418"},BT709:{BT601:"0.9137 0.0784 0.0079 0 0 -0.1049 1.1722 -0.0671 0 0 0.0096 0.0322 0.9582"},FCC:{BT709:"1.0873 -0.0736 -0.0137 0 0 0.0974 0.8494 0.0531 0 0 -0.0127 -0.0251 1.0378",BT601:"1.001 -0.0008 -0.0002 0 0 0.0009 1.005 -0.006 0 0 0.0013 0.0027 0.996"},SMPTE240M:{BT709:"0.9993 0.0006 0.0001 0 0 -0.0004 0.9812 0.0192 0 0 -0.0034 -0.0114 1.0148",BT601:"0.913 0.0774 0.0096 0 0 -0.1051 1.1508 -0.0456 0 0 0.0063 0.0207 0.973"}},s=[null,"BT601",null,"BT601","BT601","BT709","BT709","SMPTE240M","SMPTE240M","FCC","FCC"];function r(J,Z){if(!J||!Z)return null;if(J===Z)return null;let Q=y[J]?.[Z];if(!Q)return null;return`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${Q} 0 0 0 0 0 1 0'/></filter></svg>#f")`}function w(J,Z,Q,$,N){let O=Q<=0?1:Q,K=globalThis.devicePixelRatio||1;if(Z<=0||J<=0)return{width:0,height:0};let G=O<1?-1:1,F=Z*K;if(G*F*O<=G*$)F*=O;else if(G*F<G*$)F=$;if(N>0&&F>N)F=N;return J*=F/Z,Z=F,{width:J,height:Z}}function c(J,Z=J.videoWidth,Q=J.videoHeight){let $=Z/Q,{offsetWidth:N,offsetHeight:O}=J,K=N/O,G=N,F=O;if(K>$)G=Math.floor(O*$);else F=Math.floor(N/$);let X=(N-G)/2,E=(O-F)/2;return{width:G,height:F,x:X,y:E}}function m(J,Z){if(!Z)return J;let Q=J.length,$=Q-Q%16,N=3;for(;N<$;N+=16){if(J[N]<2)J[N]=1;if(J[N+4]<2)J[N+4]=1;if(J[N+8]<2)J[N+8]=1;if(J[N+12]<2)J[N+12]=1}for(;N<Q;N+=4)if(J[N]<2)J[N]=1;return J}function o(J,Z=!1){let Q=[],$=J.split(/[\r\n]+/g),N=$.length,O=null,K=null;for(let G=0;G<N;G++){let F=$[G];if(!F||/^\s*$/.test(F))continue;let X=F[0];if(X==="["){let E=F.match(/^\[(.*)\]$/);if(E){if(Z&&E[1].toLowerCase()==="events")break;O=null,K={name:E[1],body:[]},Q.push(K);continue}}if(!K)continue;if(X===";")K.body.push({type:"comment",value:F.substring(1)});else{let E=F.indexOf(":");if(E===-1)continue;let M=F.substring(0,E),Y=F.substring(E+1).trim();if(O||M==="Format"){let U=Y.split(",");if(O&&U.length>O.length){let j=U.slice(O.length-1).join(",");U=U.slice(0,O.length-1),U.push(j)}let L=U.length;for(let j=0;j<L;j++)U[j]=U[j].trim();if(O){let j={},T=Math.min(O.length,L);for(let B=0;B<T;B++)j[O[B]]=U[B];Y=j}else Y=U}if(M==="Format")O=Y;K.body.push({key:M,value:Y})}}return Q}var n=/\\blur(?:[0-9]+\.)?[0-9]+/gm;function i(J){return J.replace(n,"")}var a=[{w:7680,h:4320},{w:3840,h:2160},{w:2560,h:1440},{w:1920,h:1080},{w:1280,h:720}];function t(J,Z){let Q=[...a].sort(($,N)=>$.w-N.w);for(let $ of Q)if(J<=$.w&&Z<=$.h)return $;return{w:Math.ceil(J/100)*100,h:Math.ceil(Z/100)*100}}function k(J,Z){return Z&&Z.includes(".")?J.toFixed(2).replace(/\.?0+$/,""):Math.round(J)}function e(J){let Z=J.match(/PlayResX:\s*(\d+)/i),Q=J.match(/PlayResY:\s*(\d+)/i),$=Z?parseInt(Z[1],10):1920,N=Q?parseInt(Q[1],10):1080,O=/\\pos\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,K=/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)/g,G=/\\org\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,F=/\\i?clip\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,X=0,E=0,M=(P,q,R)=>{let H,D=new RegExp(P.source,"g");while((H=D.exec(J))!==null){for(let A of q)if(H[A]){let C=Math.abs(parseFloat(H[A]));if(C>X)X=C}for(let A of R)if(H[A]){let C=Math.abs(parseFloat(H[A]));if(C>E)E=C}}};if(M(O,[1],[2]),M(K,[1,3],[2,4]),M(G,[1],[2]),M(F,[1,3],[2,4]),X<=$&&E<=N)return J;let Y=t(X,E),U=$/Y.w,L=N/Y.h,j=Math.min(U,L),T=Math.max(U,L),B=1,V=J,W=V.match(/(\[Events\][\s\S]*)/i);if(!W)return V;let _=W[1];return _=_.replace(O,(P,q,R)=>`\\pos(${k(parseFloat(q)*U,q)},${k(parseFloat(R)*L,R)})`),_=_.replace(/\\move\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)(?:\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+))?\s*\)/g,(P,q,R,H,D,A,C)=>{let h=`\\move(${k(parseFloat(q)*U,q)},${k(parseFloat(R)*L,R)},${k(parseFloat(H)*U,H)},${k(parseFloat(D)*L,D)}`;return A?`${h},${A},${C})`:`${h})`}),_=_.replace(G,(P,q,R)=>`\\org(${k(parseFloat(q)*U,q)},${k(parseFloat(R)*L,R)})`),_=_.replace(/\\(i?clip)\s*\(\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*(-?[\d.]+)\s*\)/g,(P,q,R,H,D,A)=>`\\${q}(${k(parseFloat(R)*U,R)},${k(parseFloat(H)*L,H)},${k(parseFloat(D)*U,D)},${k(parseFloat(A)*L,A)})`),_=_.replace(/\\fs([\d.]+)/g,(P,q)=>`\\fs${k(parseFloat(q)*T,q)}`),_=_.replace(/\\fscx([\d.]+)/g,(P,q)=>`\\fscx${k(parseFloat(q)*B,q)}`),_=_.replace(/\\xbord([\d.]+)/g,(P,q)=>`\\xbord${k(parseFloat(q)*U,q)}`),_=_.replace(/\\ybord([\d.]+)/g,(P,q)=>`\\ybord${k(parseFloat(q)*L,q)}`),_=_.replace(/\\xshad(-?[\d.]+)/g,(P,q)=>`\\xshad${k(parseFloat(q)*U,q)}`),_=_.replace(/\\yshad(-?[\d.]+)/g,(P,q)=>`\\yshad${k(parseFloat(q)*L,q)}`),["fsp","bord","shad","be","blur"].forEach((P)=>{let q=new RegExp(`\\\\${P}(-?[\\d.]+)`,"g");_=_.replace(q,(R,H)=>`\\${P}${k(parseFloat(H)*j,H)}`)}),_=_.replace(/(\\i?clip\s*\([^,)]+m[^)]+\)|\\p[1-9][^}]*?)(?=[\\}]|$)/g,(P)=>{return P.replace(/(-?[\d.]+)\s+(-?[\d.]+)/g,(q,R,H)=>{return`${k(parseFloat(R)*U,R)} ${k(parseFloat(H)*L,H)}`})}),V.substring(0,W.index)+_}var b=null,S=null;async function l(){if(b!==null&&S!==null)return{hasAlphaBug:b,hasBitmapBug:S};let J=document.createElement("canvas"),Z=J.getContext("2d",{willReadFrequently:!0});if(!Z)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Q=document.createElement("canvas"),$=Q.getContext("2d",{willReadFrequently:!0});if(!$)throw Error("Canvas rendering not supported");J.width=Q.width=1,J.height=Q.height=1,Z.clearRect(0,0,1,1),$.clearRect(0,0,1,1);let N=$.getImageData(0,0,1,1).data;Z.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),$.drawImage(J,0,0);let O=$.getImageData(0,0,1,1).data;if(b=N[1]!==O[1],b)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let K=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);$.drawImage(await createImageBitmap(new ImageData(K,1)),0,0);let{data:G}=$.getImageData(0,0,1,1);S=!1;for(let F=0;F<G.length;F++)if(Math.abs(K[F]-G[F])>15){S=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else S=!1;return J.remove(),Q.remove(),{hasAlphaBug:b,hasBitmapBug:S}}async function JJ(){return l()}function ZJ(){return b}function $J(){return S}function f(){return typeof navigator<"u"&&"gpu"in navigator}function QJ(J){if(J instanceof ArrayBuffer)return new Uint8Array(J);return new Uint8Array(J.buffer,J.byteOffset,J.byteLength)}class v{device=null;context=null;pipeline=null;bindGroupLayout=null;uniformBuffer=null;imageDataBuffer=null;textureArray=null;textureArrayView=null;textureArraySize=0;textureArrayWidth=0;textureArrayHeight=0;pendingDestroyTextures=[];imageDataArray;resolutionArray=new Float32Array(2);bindGroup=null;bindGroupDirty=!0;lastCanvasWidth=0;lastCanvasHeight=0;format="bgra8unorm";_canvas=null;_initPromise=null;_initialized=!1;constructor(){this.imageDataArray=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._initDevice(),this._initPromise}async _initDevice(){if(!navigator.gpu)throw Error("WebGPU not supported");let J=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});if(!J)throw Error("No WebGPU adapter found");this.device=await J.requestDevice(),this.format=navigator.gpu.getPreferredCanvasFormat();let Z=this.device.createShaderModule({code:`
2
- struct VertexOutput {
3
- @builtin(position) position: vec4f,
4
- @location(0) @interpolate(flat) instanceIndex: u32,
5
- @location(1) @interpolate(flat) destXY: vec2f,
6
- @location(2) @interpolate(flat) texSize: vec2f,
7
- }
8
-
9
- struct Uniforms {
10
- resolution: vec2f,
11
- }
12
-
13
- struct ImageData {
14
- destRect: vec4f, // x, y, w, h
15
- texInfo: vec4f, // texW, texH, texIndex, 0
16
- }
17
-
18
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
19
- @group(0) @binding(1) var<storage, read> imageData: array<ImageData>;
20
-
21
- // Quad vertices (two triangles)
22
- const QUAD_POSITIONS = array<vec2f, 6>(
23
- vec2f(0.0, 0.0),
24
- vec2f(1.0, 0.0),
25
- vec2f(0.0, 1.0),
26
- vec2f(1.0, 0.0),
27
- vec2f(1.0, 1.0),
28
- vec2f(0.0, 1.0)
29
- );
30
-
31
- @vertex
32
- fn vertexMain(
33
- @builtin(vertex_index) vertexIndex: u32,
34
- @builtin(instance_index) instanceIndex: u32
35
- ) -> VertexOutput {
36
- var output: VertexOutput;
37
-
38
- let data = imageData[instanceIndex];
39
- let quadPos = QUAD_POSITIONS[vertexIndex];
40
- let wh = data.destRect.zw;
41
-
42
- // Calculate pixel position
43
- let pixelPos = data.destRect.xy + quadPos * wh;
44
-
45
- // Convert to clip space (-1 to 1)
46
- var clipPos = (pixelPos / uniforms.resolution) * 2.0 - 1.0;
47
- clipPos.y = -clipPos.y;
48
-
49
- output.position = vec4f(clipPos, 0.0, 1.0);
50
- output.instanceIndex = instanceIndex;
51
- output.destXY = data.destRect.xy;
52
- output.texSize = data.texInfo.xy;
53
-
54
- return output;
55
- }
56
- `}),Q=this.device.createShaderModule({code:`
57
- @group(0) @binding(2) var texArray: texture_2d_array<f32>;
58
-
59
- struct ImageData {
60
- destRect: vec4f,
61
- texInfo: vec4f,
62
- }
63
-
64
- @group(0) @binding(1) var<storage, read> imageData: array<ImageData>;
65
-
66
- struct FragmentInput {
67
- @builtin(position) fragCoord: vec4f,
68
- @location(0) @interpolate(flat) instanceIndex: u32,
69
- @location(1) @interpolate(flat) destXY: vec2f,
70
- @location(2) @interpolate(flat) texSize: vec2f,
71
- }
72
-
73
- @fragment
74
- fn fragmentMain(input: FragmentInput) -> @location(0) vec4f {
75
- let data = imageData[input.instanceIndex];
76
- let texIndex = u32(data.texInfo.z);
77
-
78
- // Calculate texel coordinates
79
- let texCoordF = floor(input.fragCoord.xy - input.destXY);
80
- let texCoord = vec2i(texCoordF);
81
-
82
- // Bounds check
83
- let texSizeI = vec2i(input.texSize);
84
- if (texCoord.x < 0 || texCoord.y < 0 || texCoord.x >= texSizeI.x || texCoord.y >= texSizeI.y) {
85
- discard;
86
- }
87
-
88
- // Load from texture array
89
- let color = textureLoad(texArray, texCoord, texIndex, 0);
90
-
91
- // Premultiplied alpha output
92
- return vec4f(color.rgb * color.a, color.a);
93
- }
94
- `});this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.imageDataBuffer=this.device.createBuffer({size:8192,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.createTextureArray(256,256,32),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float",viewDimension:"2d-array"}}]});let $=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});this.pipeline=this.device.createRenderPipeline({layout:$,vertex:{module:Z,entryPoint:"vertexMain"},fragment:{module:Q,entryPoint:"fragmentMain",targets:[{format:this.format,blend:{color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-list"}}),this._initialized=!0}roundDim(J){return Math.max(J,64)+63&-64}roundLayers(J){return Math.min(Math.max(J,8)+7&-8,256)}createTextureArray(J,Z,Q){if(this.textureArray)this.pendingDestroyTextures.push(this.textureArray);let $=this.roundDim(J),N=this.roundDim(Z),O=this.roundLayers(Q);this.textureArray=this.device.createTexture({size:[$,N,O],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.textureArrayView=this.textureArray.createView({dimension:"2d-array"}),this.textureArrayWidth=$,this.textureArrayHeight=N,this.textureArraySize=O,this.bindGroupDirty=!0;let K=this.device.createCommandEncoder();for(let G=0;G<O;G++){let F=this.textureArray.createView({dimension:"2d",baseArrayLayer:G,arrayLayerCount:1});K.beginRenderPass({colorAttachments:[{view:F,clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end()}this.device.queue.submit([K.finish()])}ensureTextureArray(J,Z,Q){let $=Math.min(Q,256);if(J<=this.textureArrayWidth&&Z<=this.textureArrayHeight&&$<=this.textureArraySize)return!1;let N=Math.max(this.textureArrayWidth,J),O=Math.max(this.textureArrayHeight,Z),K=Math.max($,Math.min(this.textureArraySize,16));return this.createTextureArray(N,O,K),!0}updateBindGroup(){if(!this.bindGroupDirty||!this.device||!this.bindGroupLayout)return;this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.uniformBuffer}},{binding:1,resource:{buffer:this.imageDataBuffer}},{binding:2,resource:this.textureArrayView}]}),this.bindGroupDirty=!1}async setCanvas(J,Z,Q){if(await this.init(),!this.device)throw Error("WebGPU device not initialized");if(Z<=0||Q<=0)return;if(this._canvas=J,J.width=Z,J.height=Q,!this.context){if(this.context=J.getContext("webgpu"),!this.context)throw Error("Could not get WebGPU context");this.context.configure({device:this.device,format:this.format,alphaMode:"premultiplied"})}this.resolutionArray[0]=Z,this.resolutionArray[1]=Q,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=Z,this.lastCanvasHeight=Q}updateSize(J,Z){if(!this.device||!this._canvas||J<=0||Z<=0)return;if(J===this.lastCanvasWidth&&Z===this.lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=Z,this.resolutionArray[0]=J,this.resolutionArray[1]=Z,this.device.queue.writeBuffer(this.uniformBuffer,0,this.resolutionArray),this.lastCanvasWidth=J,this.lastCanvasHeight=Z}renderBitmaps(J,Z,Q){if(!this.device||!this.context||!this.pipeline)return;let $=J.length;if($===0){this.clear();return}let N=this.context.getCurrentTexture();if(N.width===0||N.height===0)return;let O=0,K=0,G=0;for(let T=0;T<$;T++){let{image:B}=J[T],V=B.width,W=B.height;if(V>0&&W>0){if(V>O)O=V;if(W>K)K=W;G++}}if(G===0){this.clear();return}let F=Math.min(G,256);this.ensureTextureArray(O,K,F),this.updateBindGroup();let X=this.device,E=X.queue,M=this.textureArray,Y=this.imageDataArray,U=N.createView(),L=0,j=!0;while(L<$){let T=0;while(L<$&&T<256){let W=J[L++],_=W.image,I=_.width,P=_.height;if(I<=0||P<=0)continue;E.copyExternalImageToTexture({source:_,flipY:!1},{texture:M,origin:[0,0,T],premultipliedAlpha:!1},{width:I,height:P});let q=T<<3;Y[q]=W.x,Y[q+1]=W.y,Y[q+2]=I,Y[q+3]=P,Y[q+4]=I,Y[q+5]=P,Y[q+6]=T,Y[q+7]=0,T++}if(T===0)continue;E.writeBuffer(this.imageDataBuffer,0,Y.buffer,0,T<<5);let B=X.createCommandEncoder(),V=B.beginRenderPass({colorAttachments:[{view:U,clearValue:{r:0,g:0,b:0,a:0},loadOp:j?"clear":"load",storeOp:"store"}]});V.setPipeline(this.pipeline),V.setBindGroup(0,this.bindGroup),V.draw(6,T),V.end(),E.submit([B.finish()]),j=!1}this.cleanupPendingTextures()}render(J,Z,Q){if(!this.device||!this.context||!this.pipeline)return;let $=J.length;if($===0){this.clear();return}let N=this.context.getCurrentTexture();if(N.width===0||N.height===0)return;let O=0,K=0,G=0;for(let T=0;T<$;T++){let{w:B,h:V}=J[T];if(B>0&&V>0){if(B>O)O=B;if(V>K)K=V;G++}}if(G===0){this.clear();return}let F=Math.min(G,256);this.ensureTextureArray(O,K,F),this.updateBindGroup();let X=this.device,E=X.queue,M=this.textureArray,Y=this.imageDataArray,U=N.createView(),L=0,j=!0;while(L<$){let T=0;while(L<$&&T<256){let W=J[L++],_=W.w,I=W.h;if(_<=0||I<=0)continue;let P=W.image;if(P instanceof ImageBitmap)E.copyExternalImageToTexture({source:P,flipY:!1},{texture:M,origin:[0,0,T],premultipliedAlpha:!1},{width:_,height:I});else if(P instanceof ArrayBuffer||P instanceof Uint8Array||P instanceof Uint8ClampedArray)this.uploadTextureData(T,P,_,I);let q=T<<3;Y[q]=W.x,Y[q+1]=W.y,Y[q+2]=_,Y[q+3]=I,Y[q+4]=_,Y[q+5]=I,Y[q+6]=T,Y[q+7]=0,T++}if(T===0)continue;E.writeBuffer(this.imageDataBuffer,0,Y.buffer,0,T<<5);let B=X.createCommandEncoder(),V=B.beginRenderPass({colorAttachments:[{view:U,clearValue:{r:0,g:0,b:0,a:0},loadOp:j?"clear":"load",storeOp:"store"}]});V.setPipeline(this.pipeline),V.setBindGroup(0,this.bindGroup),V.draw(6,T),V.end(),E.submit([B.finish()]),j=!1}this.cleanupPendingTextures()}uploadTextureData(J,Z,Q,$){this.device.queue.writeTexture({texture:this.textureArray,origin:[0,0,J]},QJ(Z),{bytesPerRow:Q*4},{width:Q,height:$})}cleanupPendingTextures(){let J=this.pendingDestroyTextures,Z=J.length;if(Z===0)return;for(let Q=0;Q<Z;Q++)J[Q].destroy();J.length=0}clear(){if(!this.device||!this.context)return;try{let J=this.context.getCurrentTexture();if(J.width===0||J.height===0)return;let Z=this.device.createCommandEncoder();Z.beginRenderPass({colorAttachments:[{view:J.createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]}).end(),this.device.queue.submit([Z.finish()])}catch{}}get initialized(){return this._initialized}destroy(){this.cleanupPendingTextures(),this.textureArray?.destroy(),this.textureArray=null,this.textureArrayView=null,this.uniformBuffer?.destroy(),this.uniformBuffer=null,this.imageDataBuffer?.destroy(),this.imageDataBuffer=null,this.bindGroup=null,this.device?.destroy(),this.device=null,this.context=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}function p(){if(typeof document>"u")return!1;try{return document.createElement("canvas").getContext("webgl2")!==null}catch{return!1}}function KJ(J){return J instanceof Uint8Array||J instanceof Uint8ClampedArray}function g(J,Z,Q){let $=J.createShader(Z);if(J.shaderSource($,Q),J.compileShader($),!J.getShaderParameter($,J.COMPILE_STATUS)){let N=J.getShaderInfoLog($);throw J.deleteShader($),Error(`WebGL2 shader compilation failed: ${N}`)}return $}class x{_gl=null;_canvas=null;_program=null;_vao=null;_instanceBuffer=null;_texArray=null;_texWidth=0;_texHeight=0;_texLayers=0;_resolutionLoc=null;_texArraySizeLoc=null;_instanceData;_lastCanvasWidth=0;_lastCanvasHeight=0;_initialized=!1;_initPromise=null;constructor(){this._instanceData=new Float32Array(2048)}async init(){if(this._initPromise)return this._initPromise;return this._initPromise=this._checkSupport(),this._initPromise}async _checkSupport(){if(typeof document>"u")throw Error("WebGL2 requires a DOM environment");if(!document.createElement("canvas").getContext("webgl2"))throw Error("WebGL2 not supported")}_initGL(){if(!this._canvas)throw Error("Canvas not set before _initGL");if(this._gl)return;let J=this._canvas.getContext("webgl2",{alpha:!0,premultipliedAlpha:!0,antialias:!1});if(!J)throw Error("Failed to create WebGL2 context");this._gl=J;let Z=g(J,J.VERTEX_SHADER,`#version 300 es
95
- precision highp float;
96
-
97
- in vec4 a_destRect;
98
- in vec4 a_texInfo;
99
-
100
- uniform vec2 u_resolution;
101
-
102
- out vec2 v_uv;
103
- flat out int v_texIndex;
104
- flat out vec2 v_texSize;
105
-
106
- vec2 quadPos(int id) {
107
- if (id == 0) return vec2(0.0, 0.0);
108
- if (id == 1) return vec2(1.0, 0.0);
109
- if (id == 2) return vec2(0.0, 1.0);
110
- if (id == 3) return vec2(1.0, 0.0);
111
- if (id == 4) return vec2(1.0, 1.0);
112
- return vec2(0.0, 1.0);
113
- }
114
-
115
- void main() {
116
- vec2 qp = quadPos(gl_VertexID);
117
- vec2 pixelPos = a_destRect.xy + qp * a_destRect.zw;
118
-
119
- // Convert CSS pixel coords (y=0 top) to GL clip space (y=1 top)
120
- vec2 clip = (pixelPos / u_resolution) * 2.0 - 1.0;
121
- clip.y = -clip.y;
122
-
123
- gl_Position = vec4(clip, 0.0, 1.0);
124
- v_uv = qp;
125
- v_texIndex = int(a_texInfo.z);
126
- v_texSize = a_texInfo.xy;
127
- }
128
- `),Q=g(J,J.FRAGMENT_SHADER,`#version 300 es
129
- precision highp float;
130
- precision highp sampler2DArray;
131
-
132
- uniform sampler2DArray u_texArray;
133
- uniform ivec2 u_texArraySize;
134
-
135
- in vec2 v_uv;
136
- flat in int v_texIndex;
137
- flat in vec2 v_texSize;
138
-
139
- out vec4 fragColor;
140
-
141
- void main() {
142
- vec2 normalizedCoord = v_uv * v_texSize / vec2(u_texArraySize);
143
- vec4 color = texture(u_texArray, vec3(normalizedCoord, float(v_texIndex)));
144
- // Premultiplied alpha output (matches WebGPU renderer behaviour)
145
- fragColor = vec4(color.rgb * color.a, color.a);
146
- }
147
- `),$=J.createProgram();if(J.attachShader($,Z),J.attachShader($,Q),J.linkProgram($),!J.getProgramParameter($,J.LINK_STATUS))throw Error(`WebGL2 program link failed: ${J.getProgramInfoLog($)}`);J.deleteShader(Z),J.deleteShader(Q),this._program=$,this._resolutionLoc=J.getUniformLocation($,"u_resolution"),this._texArraySizeLoc=J.getUniformLocation($,"u_texArraySize"),this._vao=J.createVertexArray(),J.bindVertexArray(this._vao),this._instanceBuffer=J.createBuffer(),J.bindBuffer(J.ARRAY_BUFFER,this._instanceBuffer),J.bufferData(J.ARRAY_BUFFER,8192,J.DYNAMIC_DRAW);let N=J.getAttribLocation($,"a_destRect");J.enableVertexAttribArray(N),J.vertexAttribPointer(N,4,J.FLOAT,!1,32,0),J.vertexAttribDivisor(N,1);let O=J.getAttribLocation($,"a_texInfo");J.enableVertexAttribArray(O),J.vertexAttribPointer(O,4,J.FLOAT,!1,32,16),J.vertexAttribDivisor(O,1),J.bindVertexArray(null),this._allocateTextureArray(256,256,32),J.enable(J.BLEND),J.blendEquation(J.FUNC_ADD),J.blendFunc(J.ONE,J.ONE_MINUS_SRC_ALPHA),this._initialized=!0}_roundDim(J){return Math.max(J,64)+63&-64}_roundLayers(J){return Math.min(Math.max(J,8)+7&-8,256)}_allocateTextureArray(J,Z,Q){let $=this._gl,N=this._roundDim(J),O=this._roundDim(Z),K=this._roundLayers(Q);if(this._texArray)$.deleteTexture(this._texArray);this._texArray=$.createTexture(),$.bindTexture($.TEXTURE_2D_ARRAY,this._texArray),$.texStorage3D($.TEXTURE_2D_ARRAY,1,$.RGBA8,N,O,K),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_MIN_FILTER,$.NEAREST),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_MAG_FILTER,$.NEAREST),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_WRAP_S,$.CLAMP_TO_EDGE),$.texParameteri($.TEXTURE_2D_ARRAY,$.TEXTURE_WRAP_T,$.CLAMP_TO_EDGE),this._texWidth=N,this._texHeight=O,this._texLayers=K}_ensureTextureArray(J,Z,Q){let $=Math.min(Q,256);if(J<=this._texWidth&&Z<=this._texHeight&&$<=this._texLayers)return;let N=Math.max(this._texWidth,J),O=Math.max(this._texHeight,Z),K=Math.max($,Math.min(this._texLayers,16));this._allocateTextureArray(N,O,K)}async setCanvas(J,Z,Q){if(await this.init(),Z<=0||Q<=0)return;this._canvas=J,J.width=Z,J.height=Q,this._initGL(),this._gl.viewport(0,0,Z,Q),this._lastCanvasWidth=Z,this._lastCanvasHeight=Q}updateSize(J,Z){if(!this._gl||!this._canvas||J<=0||Z<=0)return;if(J===this._lastCanvasWidth&&Z===this._lastCanvasHeight)return;this._canvas.width=J,this._canvas.height=Z,this._gl.viewport(0,0,J,Z),this._lastCanvasWidth=J,this._lastCanvasHeight=Z}renderBitmaps(J,Z,Q){if(!this._gl||!this._initialized)return;let $=J.length;if($===0){this.clear();return}let N=0,O=0;for(let X=0;X<$;X++){let{image:E}=J[X];if(E.width>N)N=E.width;if(E.height>O)O=E.height}this._ensureTextureArray(N,O,Math.min($,256));let K=this._gl;K.clearColor(0,0,0,0),K.clear(K.COLOR_BUFFER_BIT),K.useProgram(this._program),K.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),K.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),K.activeTexture(K.TEXTURE0),K.bindTexture(K.TEXTURE_2D_ARRAY,this._texArray),K.pixelStorei(K.UNPACK_FLIP_Y_WEBGL,!1);let G=this._instanceData,F=0;while(F<$){let X=0;while(F<$&&X<256){let E=J[F++],M=E.image.width,Y=E.image.height;if(M<=0||Y<=0)continue;K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,X,M,Y,1,K.RGBA,K.UNSIGNED_BYTE,E.image);let U=X<<3;G[U]=E.x,G[U+1]=E.y,G[U+2]=M,G[U+3]=Y,G[U+4]=M,G[U+5]=Y,G[U+6]=X,G[U+7]=0,X++}if(X===0)continue;K.bindBuffer(K.ARRAY_BUFFER,this._instanceBuffer),K.bufferSubData(K.ARRAY_BUFFER,0,G,0,X<<3),K.bindVertexArray(this._vao),K.drawArraysInstanced(K.TRIANGLES,0,6,X),K.bindVertexArray(null)}}render(J,Z,Q){if(!this._gl||!this._initialized)return;let $=J.length;if($===0){this.clear();return}let N=0,O=0;for(let X=0;X<$;X++){let{w:E,h:M}=J[X];if(E>N)N=E;if(M>O)O=M}this._ensureTextureArray(N,O,Math.min($,256));let K=this._gl;K.clearColor(0,0,0,0),K.clear(K.COLOR_BUFFER_BIT),K.useProgram(this._program),K.uniform2f(this._resolutionLoc,this._lastCanvasWidth,this._lastCanvasHeight),K.uniform2i(this._texArraySizeLoc,this._texWidth,this._texHeight),K.activeTexture(K.TEXTURE0),K.bindTexture(K.TEXTURE_2D_ARRAY,this._texArray),K.pixelStorei(K.UNPACK_FLIP_Y_WEBGL,!1);let G=this._instanceData,F=0;while(F<$){let X=0;while(F<$&&X<256){let E=J[F++],M=E.w,Y=E.h;if(M<=0||Y<=0)continue;let U=E.image;if(U instanceof ImageBitmap)K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,X,M,Y,1,K.RGBA,K.UNSIGNED_BYTE,U);else if(U instanceof ArrayBuffer||KJ(U)){let j=U instanceof ArrayBuffer?new Uint8Array(U):U;K.texSubImage3D(K.TEXTURE_2D_ARRAY,0,0,0,X,M,Y,1,K.RGBA,K.UNSIGNED_BYTE,j)}let L=X<<3;G[L]=E.x,G[L+1]=E.y,G[L+2]=M,G[L+3]=Y,G[L+4]=M,G[L+5]=Y,G[L+6]=X,G[L+7]=0,X++}if(X===0)continue;K.bindBuffer(K.ARRAY_BUFFER,this._instanceBuffer),K.bufferSubData(K.ARRAY_BUFFER,0,G,0,X<<3),K.bindVertexArray(this._vao),K.drawArraysInstanced(K.TRIANGLES,0,6,X),K.bindVertexArray(null)}}clear(){if(!this._gl)return;this._gl.clearColor(0,0,0,0),this._gl.clear(this._gl.COLOR_BUFFER_BIT)}get initialized(){return this._initialized}destroy(){let J=this._gl;if(J)J.deleteProgram(this._program),J.deleteVertexArray(this._vao),J.deleteBuffer(this._instanceBuffer),J.deleteTexture(this._texArray);this._gl=null,this._program=null,this._vao=null,this._instanceBuffer=null,this._texArray=null,this._canvas=null,this._initialized=!1,this._initPromise=null}}var d=0.008,NJ=d*1000,OJ=16,GJ=()=>{if(typeof navigator>"u")return!1;let J=navigator.userAgent||"",Z=navigator.vendor||"",Q=/\b(iPhone|iPad|iPod)\b/i.test(J);if(!/AppleWebKit/i.test(J))return!1;if(Q)return!0;if(/\b(Chrome|Chromium|Edg|OPR|SamsungBrowser|Firefox)\b/i.test(J))return!1;return Z.includes("Apple")};class z extends EventTarget{static MAX_PENDING_DEMANDS=3;static _hasAlphaBug=null;static _hasBitmapBug=null;_loaded;_init;_onDemandRender;_offscreenRender;_video;_videoWidth=0;_videoHeight=0;_videoColorSpace=null;_canvas;_canvasParent;_bufferCanvas;_bufferCtx;_canvasctrl;_ctx=null;_lastRenderTime=0;_playstate=!0;_destroyed=!1;_workerReady=!1;_ro;_worker;_pendingDemandTimes=[];_isLikelyWebKit;_activeDemandStartedAt=0;_smoothedDemandLatencyMs;_boundResize;_boundTimeUpdate;_boundSetRate;_boundUpdateColorSpace;_boundHandleRVFC;_gpuRenderer=null;_rendererType="canvas2d";_onCanvasFallback;_lastRenderWidth=0;_lastRenderHeight=0;_gpuBitmapImages=[];timeOffset;debug;prescaleFactor;prescaleHeightLimit;maxRenderHeight;busy=!1;renderAhead;constructor(J){super();if(!globalThis.Worker)throw this.destroy(Error("Worker not supported"));if(!J)throw this.destroy(Error("No options provided"));this._loaded=new Promise((O)=>{this._init=O}),this._isLikelyWebKit=GJ(),this._smoothedDemandLatencyMs=this._isLikelyWebKit?OJ:NJ;let Z=z._test();this._onDemandRender="requestVideoFrameCallback"in HTMLVideoElement.prototype&&(J.onDemandRender??!0),this._onCanvasFallback=J.onCanvasFallback;let Q=!this._isLikelyWebKit&&!J.canvas&&(f()||p()),$=typeof createImageBitmap<"u"&&(J.asyncRender??(!this._isLikelyWebKit&&!Q));if(this._offscreenRender="transferControlToOffscreen"in HTMLCanvasElement.prototype&&!J.canvas&&!Q&&(J.offscreenRender??!0),this.timeOffset=J.timeOffset||0,this._video=J.video,this._canvas=J.canvas,this._video&&!this._canvas)this._canvasParent=document.createElement("div"),this._canvasParent.className="AkariSub",this._canvasParent.style.position="relative",this._canvas=this._createCanvas(),this._video.insertAdjacentElement("afterend",this._canvasParent);else if(!this._canvas)throw this.destroy(Error("Don't know where to render: you should give video or canvas in options."));this._bufferCanvas=document.createElement("canvas");let N=this._bufferCanvas.getContext("2d");if(!N)throw this.destroy(Error("Canvas rendering not supported"));if(this._bufferCtx=N,Q)this._initGPURenderer();else if(!this._offscreenRender)this._ctx=this._canvas.getContext("2d",{alpha:!0,desynchronized:!0});if(this._canvasctrl=this._offscreenRender?this._canvas.transferControlToOffscreen():this._canvas,this._lastRenderTime=0,this.debug=!!J.debug,this.prescaleFactor=J.prescaleFactor||1,this.prescaleHeightLimit=J.prescaleHeightLimit||1080,this.maxRenderHeight=J.maxRenderHeight||0,this.renderAhead=J.renderAhead??d,this._boundResize=this.resize.bind(this),this._boundTimeUpdate=this._timeupdate.bind(this),this._boundSetRate=()=>this.setRate(this._video.playbackRate),this._boundUpdateColorSpace=this._updateColorSpace.bind(this),this._boundHandleRVFC=this._handleRVFC.bind(this),this._video)this.setVideo(this._video);if(this._onDemandRender)this.busy=!1,this._pendingDemandTimes.length=0;this._worker=new Worker(J.workerUrl||"akarisub-worker.js"),this._worker.onmessage=(O)=>this._onmessage(O),this._worker.onerror=(O)=>this._error(O),Z.then(()=>{let O={target:"init",wasmUrl:J.wasmUrl??"akarisub-worker.wasm",asyncRender:$,fullTrackWarmup:J.fullTrackWarmup??!1,onDemandRender:this._onDemandRender,initialTime:(this._video?.currentTime??0)+this.timeOffset,width:this._canvasctrl.width||0,height:this._canvasctrl.height||0,blendMode:J.blendMode??"wasm",subUrl:J.subUrl,subContent:J.subContent||null,encryptedSubContent:J.encryptedSubContent||null,fonts:J.fonts||[],availableFonts:J.availableFonts||{"liberation sans":"./default.woff2"},fallbackFonts:J.fallbackFonts||["liberation sans"],debug:this.debug,targetFps:J.targetFps||24,dropAllAnimations:J.dropAllAnimations,dropAllBlur:J.dropAllBlur,clampPos:J.clampPos,libassMemoryLimit:J.libassMemoryLimit??128,libassGlyphLimit:J.libassGlyphLimit??2048,useLocalFonts:typeof globalThis.queryLocalFonts<"u"&&(J.useLocalFonts??!0),hasBitmapBug:z._hasBitmapBug};if(this._worker.postMessage(O,z._getSubtitleTransfers(J.subContent,J.encryptedSubContent)),this._offscreenRender)this.sendMessage("offscreenCanvas",{},[this._canvasctrl])})}static async _testImageBugs(){if(z._hasBitmapBug!==null)return;let J=document.createElement("canvas"),Z=J.getContext("2d",{willReadFrequently:!0});if(!Z)throw Error("Canvas rendering not supported");if(typeof ImageData.prototype.constructor==="function")try{new ImageData(new Uint8ClampedArray([0,0,0,0]),1,1)}catch{console.log("Detected that ImageData is not constructable despite browser saying so")}let Q=document.createElement("canvas"),$=Q.getContext("2d",{willReadFrequently:!0});if(!$)throw Error("Canvas rendering not supported");J.width=Q.width=1,J.height=Q.height=1,Z.clearRect(0,0,1,1),$.clearRect(0,0,1,1);let N=$.getImageData(0,0,1,1).data;Z.putImageData(new ImageData(new Uint8ClampedArray([0,255,0,0]),1,1),0,0),$.drawImage(J,0,0);let O=$.getImageData(0,0,1,1).data;if(z._hasAlphaBug=N[1]!==O[1],z._hasAlphaBug)console.log("Detected a browser having issue with transparent pixels, applying workaround");if(typeof createImageBitmap<"u"){let K=new Uint8ClampedArray([255,0,255,0,255]).subarray(1,5);$.drawImage(await createImageBitmap(new ImageData(K,1)),0,0);let{data:G}=$.getImageData(0,0,1,1);z._hasBitmapBug=!1;for(let F=0;F<G.length;F++)if(Math.abs(K[F]-G[F])>15){z._hasBitmapBug=!0,console.log("Detected a browser having issue with partial bitmaps, applying workaround");break}}else z._hasBitmapBug=!1;J.remove(),Q.remove()}static async _test(){await z._testImageBugs()}static _getSubtitleTransfers(J,Z){let Q=[];if(J instanceof ArrayBuffer)Q.push(J);else if(J instanceof Uint8Array)Q.push(J.buffer);if(Z?.encrypted)Q.push(Z.encrypted);for(let $ of Z?.encryptedChunks||[])Q.push($);return Q}async _initGPURenderer(){if(f())try{let J=new v;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgpu",console.log("[AkariSub] Using WebGPU renderer");return}catch(J){console.warn("[AkariSub] WebGPU init failed, trying WebGL2:",J)}if(p())try{let J=new x;if(await J.init(),!this._canvas)return;await J.setCanvas(this._canvas,Math.max(1,this._canvas.width||1),Math.max(1,this._canvas.height||1)),this._gpuRenderer=J,this._rendererType="webgl2",console.log("[AkariSub] Using WebGL2 renderer");return}catch(J){console.warn("[AkariSub] WebGL2 init failed, falling back to Canvas2D:",J)}if(this._rendererType="canvas2d",!this._offscreenRender&&!this._ctx)this._ctx=this._canvas.getContext("2d",{alpha:!0,desynchronized:!0});this.sendMessage("setAsyncRender",{value:!1}),this._onCanvasFallback?.()}get rendererType(){return this._rendererType}get isUsingWebGPU(){return this._rendererType==="webgpu"}get isUsingGPURenderer(){return this._gpuRenderer!==null}_createCanvas(){return this._canvas=document.createElement("canvas"),this._canvas.style.display="block",this._canvas.style.position="absolute",this._canvas.style.pointerEvents="none",this._canvasParent.appendChild(this._canvas),this._canvas}resize(J=0,Z=0,Q=0,$=0,N=this._video?.paused??!1){if((!J||!Z)&&this._video){let O=c(this._video),K;if(this._videoWidth){let G=this._video.videoWidth/this._videoWidth,F=this._video.videoHeight/this._videoHeight;K=w((O.width||0)/G,(O.height||0)/F,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight)}else K=w(O.width||0,O.height||0,this.prescaleFactor,this.prescaleHeightLimit,this.maxRenderHeight);if(J=K.width,Z=K.height,this._canvasParent)Q=O.y-(this._canvasParent.getBoundingClientRect().top-this._video.getBoundingClientRect().top),$=O.x;this._canvas.style.width=O.width+"px",this._canvas.style.height=O.height+"px"}if(this._canvas.style.top=Q+"px",this._canvas.style.left=$+"px",J>0&&Z>0)this._canvasctrl.width=J,this._canvasctrl.height=Z;if(this._gpuRenderer&&J>0&&Z>0)this._gpuRenderer.updateSize(J,Z);if(N&&this.busy===!1)this.busy=!0;else N=!1;this.sendMessage("canvas",{width:J,height:Z,videoWidth:this._videoWidth||this._video?.videoWidth||0,videoHeight:this._videoHeight||this._video?.videoHeight||0,force:N})}_timeupdate(J){let Q={seeking:!0,waiting:!0,playing:!1}[J.type];if(Q!=null)this._playstate=Q;this.setCurrentTime(this._video.paused||this._playstate,this._video.currentTime+this.timeOffset)}setVideo(J){if(J instanceof HTMLVideoElement){if(this._removeListeners(),this._video=J,this._onDemandRender){if(!this._destroyed&&this._video===J)J.requestVideoFrameCallback(this._boundHandleRVFC)}else this._playstate=J.paused,J.addEventListener("timeupdate",this._boundTimeUpdate,!1),J.addEventListener("progress",this._boundTimeUpdate,!1),J.addEventListener("waiting",this._boundTimeUpdate,!1),J.addEventListener("seeking",this._boundTimeUpdate,!1),J.addEventListener("playing",this._boundTimeUpdate,!1),J.addEventListener("ratechange",this._boundSetRate,!1),J.addEventListener("resize",this._boundResize,!1);if("VideoFrame"in window){if(J.addEventListener("loadedmetadata",this._boundUpdateColorSpace,!1),J.readyState>2)this._updateColorSpace()}if(J.videoWidth>0)this.resize();if(typeof ResizeObserver<"u"){if(!this._ro)this._ro=new ResizeObserver(()=>this.resize());this._ro.observe(J)}}else this._error(Error("Video element invalid!"))}setTrackByUrl(J){if(this.sendMessage("setTrackByUrl",{url:J}),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setTrack(J){if(this.sendMessage("setTrack",{content:J},z._getSubtitleTransfers(J)),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}setEncryptedTrack(J){if(this.sendMessage("setEncryptedTrack",{content:J},z._getSubtitleTransfers(void 0,J)),this._reAttachOffscreen(),this._ctx)this._ctx.filter="none"}freeTrack(){this.sendMessage("freeTrack")}setIsPaused(J){this.sendMessage("video",{isPaused:J})}setRate(J){this.sendMessage("video",{rate:J})}setCurrentTime(J,Z,Q){this.sendMessage("video",{isPaused:J,currentTime:Z,rate:Q,colorSpace:this._videoColorSpace})}createEvent(J){this.sendMessage("createEvent",{event:J})}setEvent(J,Z){this.sendMessage("setEvent",{event:J,index:Z})}removeEvent(J){this.sendMessage("removeEvent",{index:J})}async getEvents(){return(await this._fetchFromWorker({target:"getEvents"})).events??[]}styleOverride(J){this.sendMessage("styleOverride",{style:J})}disableStyleOverride(){this.sendMessage("disableStyleOverride")}createStyle(J){this.sendMessage("createStyle",{style:J})}setStyle(J,Z){this.sendMessage("setStyle",{style:J,index:Z})}removeStyle(J){this.sendMessage("removeStyle",{index:J})}async getStyles(){return(await this._fetchFromWorker({target:"getStyles"})).styles??[]}addFont(J){this.sendMessage("addFont",{font:J})}setDefaultFont(J){this.sendMessage("defaultFont",{font:J})}async getStats(){let Z=(await this._fetchFromWorker({target:"getStats"})).stats;return{framesRendered:Z.framesRendered??0,framesDropped:Z.framesDropped??0,avgRenderTime:Z.avgRenderTime??0,maxRenderTime:Z.maxRenderTime??0,minRenderTime:Z.minRenderTime??0,lastRenderTime:Z.lastRenderTime??0,pendingRenders:Z.pendingRenders??0,totalEvents:Z.totalEvents??0,cacheHits:Z.cacheHits??0,cacheMisses:Z.cacheMisses??0,renderFps:Z.avgRenderTime&&Z.avgRenderTime>0?Math.round(1000/Z.avgRenderTime):0,usingWorker:!0,offscreenRender:this._offscreenRender,onDemandRender:this._onDemandRender}}async resetStats(){await this._fetchFromWorker({target:"resetStats"})}async getEventCount(){return(await this._fetchFromWorker({target:"getEventCount"})).count}async getStyleCount(){return(await this._fetchFromWorker({target:"getStyleCount"})).count}_sendLocalFont(J){try{globalThis.queryLocalFonts().then((Z)=>{let Q=Z?.find(($)=>$.fullName.toLowerCase()===J);if(Q)Q.blob().then(($)=>{$.arrayBuffer().then((N)=>{this.addFont(new Uint8Array(N))})})})}catch(Z){console.warn("Local fonts API:",Z)}}_getLocalFont(J){try{if(navigator?.permissions?.query)navigator.permissions.query({name:"local-fonts"}).then((Z)=>{if(Z.state==="granted")this._sendLocalFont(J.font)});else this._sendLocalFont(J.font)}catch(Z){console.warn("Local fonts API:",Z)}}_unbusy(){if(this._observeDemandCompletion(),this._pendingDemandTimes.length>0){if(this._pendingDemandTimes.length>1){let Z=this._pendingDemandTimes[this._pendingDemandTimes.length-1];this._pendingDemandTimes.length=0,this._pendingDemandTimes.push(Z)}let J=this._pendingDemandTimes.shift();if(J){this._demandRender(J);return}}this.busy=!1}_markDemandDispatched(){if(!this._onDemandRender)return;this._activeDemandStartedAt=performance.now()}_observeDemandCompletion(){if(!this._onDemandRender||this._activeDemandStartedAt===0)return;let J=performance.now()-this._activeDemandStartedAt;if(this._activeDemandStartedAt=0,!Number.isFinite(J)||J<=0)return;this._smoothedDemandLatencyMs=this._smoothedDemandLatencyMs<=0?J:this._smoothedDemandLatencyMs*0.75+J*0.25}_getDemandPipelineLeadSeconds(J,Z){let Q=Z.expectedDisplayTime??Z.presentationTime??J,$=Math.max(0,Q-J)/1000;return Math.max(0,this._smoothedDemandLatencyMs/1000-$)}_enqueueDemand(J){let Z=this._pendingDemandTimes;if(Z.length>0){let Q=Z[Z.length-1];if(Math.abs(Q.mediaTime-J.mediaTime)>0.25)Z.length=0}if(Z.length>=z.MAX_PENDING_DEMANDS)Z.shift();Z.push(J)}_handleRVFC(J,Z){if(this._destroyed)return;let Q=this._video?.playbackRate??1,$=this._getDemandPipelineLeadSeconds(J,Z),O={mediaTime:Z.mediaTime+($+this.renderAhead)*Q,width:Z.width,height:Z.height};if(!this._workerReady){this._enqueueDemand(O),this._video.requestVideoFrameCallback(this._boundHandleRVFC);return}if(this.busy)this._enqueueDemand(O);else this.busy=!0,this._demandRender(O);this._video.requestVideoFrameCallback(this._boundHandleRVFC)}_demandRender(J){if(J.width!==this._videoWidth||J.height!==this._videoHeight)this._videoWidth=J.width,this._videoHeight=J.height,this.resize();this._markDemandDispatched(),this.sendMessage("demand",{time:J.mediaTime+this.timeOffset})}_detachOffscreen(){if(!this._offscreenRender||this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas,this._ctx=this._canvasctrl.getContext("2d",{alpha:!0,desynchronized:!0}),this.sendMessage("detachOffscreen"),this.busy=!1,this._activeDemandStartedAt=0,this._pendingDemandTimes.length=0,this.resize(0,0,0,0,!0)}_reAttachOffscreen(){if(!this._offscreenRender||!this._ctx)return;this._canvas.remove(),this._createCanvas(),this._canvasctrl=this._canvas.transferControlToOffscreen(),this._ctx=!1,this.sendMessage("offscreenCanvas",{},[this._canvasctrl]),this.resize(0,0,0,0,!0)}_updateColorSpace(){this._video.requestVideoFrameCallback(()=>{try{let J=new globalThis.VideoFrame(this._video);this._videoColorSpace=u[J.colorSpace.matrix]??null,J.close(),this.sendMessage("getColorSpace")}catch(J){console.warn(J)}})}_verifyColorSpace(J){let{subtitleColorSpace:Z,videoColorSpace:Q=this._videoColorSpace}=J;if(!Z||!Q)return;if(Z===Q)return;this._detachOffscreen();let $=y[Z]?.[Q];if($&&this._ctx)this._ctx.filter=`url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${$} 0 0 0 0 0 1 0'/></filter></svg>#f")`}_render(J){try{let{width:Z,height:Q}=J;if(this.debug)J.times.IPCTime=Date.now()-(J.times.JSRenderTime||0);if(this._canvasctrl.width!==Z||this._canvasctrl.height!==Q){if(this._canvasctrl.width=Z,this._canvasctrl.height=Q,this._lastRenderWidth=Z,this._lastRenderHeight=Q,this._gpuRenderer)this._gpuRenderer.updateSize(Z,Q);this._verifyColorSpace({subtitleColorSpace:J.colorSpace})}if(this._gpuRenderer){this._renderGPU(J);return}if(!this._ctx)return;let N=this._ctx,O=J.images,K=O.length;if(N.clearRect(0,0,Z,Q),J.asyncRender)for(let G=0;G<K;G++){let F=O[G];if(F.image)N.drawImage(F.image,F.x,F.y),F.image.close()}else{let G=z._hasAlphaBug??!1;for(let F=0;F<K;F++){let X=O[F];if(X.image){let{w:E,h:M,image:Y}=X,U=Y instanceof Uint8ClampedArray?Y:Y instanceof Uint8Array?new Uint8ClampedArray(Y.buffer,Y.byteOffset,Y.byteLength):new Uint8ClampedArray(Y),L=m(U,G);N.putImageData(new ImageData(L,E,M),X.x,X.y)}}}if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let G=0,F=J.times.bitmaps||K;delete J.times.bitmaps;for(let X in J.times)G+=J.times[X]||0;console.log("Bitmaps: "+F+" Total: "+(G|0)+"ms",J.times)}}finally{this._unbusy()}}_renderGPU(J){let Z=this._gpuRenderer;if(!Z)return;if(J.images.length===0){Z.clear();return}if(J.asyncRender){let Q=this._gpuBitmapImages,$=0;for(let N=0;N<J.images.length;N++){let O=J.images[N];if(!(O.image instanceof ImageBitmap))continue;let K=Q[$]||(Q[$]={image:O.image,x:0,y:0});K.image=O.image,K.x=O.x,K.y=O.y,$++}Q.length=$,Z.renderBitmaps(Q,this._canvasctrl.width,this._canvasctrl.height);for(let N of J.images)if(N.image instanceof ImageBitmap)N.image.close()}else Z.render(J.images,this._canvasctrl.width,this._canvasctrl.height);if(this.debug){J.times.JSRenderTime=Date.now()-(J.times.JSRenderTime||0)-(J.times.IPCTime||0);let Q=0,$=J.times.bitmaps||J.images.length;delete J.times.bitmaps;for(let N in J.times)Q+=J.times[N]||0;console.log(`[${this._rendererType.toUpperCase()}] Bitmaps: `+$+" Total: "+(Q|0)+"ms",J.times)}}_ready(){if(this._workerReady=!0,this._init(),this._onDemandRender&&this._video){this.setCurrentTime(this._video.paused,this._video.currentTime+this.timeOffset,this._video.playbackRate);let J=this._pendingDemandTimes.length>0?this._pendingDemandTimes[this._pendingDemandTimes.length-1]:{mediaTime:this._video.currentTime+this.renderAhead*(this._video.playbackRate||1),width:this._video.videoWidth,height:this._video.videoHeight};this._pendingDemandTimes.length=0,this.busy=!0,this._demandRender(J)}this.dispatchEvent(new CustomEvent("ready"))}_partial_ready(){this.dispatchEvent(new CustomEvent("partial_ready"))}_trackReady(){this.dispatchEvent(new CustomEvent("trackReady"))}async sendMessage(J,Z={},Q){if(await this._loaded,Q)this._worker.postMessage({target:J,transferable:Q,...Z},[...Q]);else this._worker.postMessage({target:J,...Z})}_fetchFromWorker(J){return new Promise((Z,Q)=>{try{let $=J.target,N=setTimeout(()=>{G(),Q(Error("Error: Timeout while trying to fetch "+$))},5000),O=(F)=>{if(F.data.target===$)G(),Z(F.data)},K=(F)=>{G(),Q(F instanceof Error?F:F.error||Error("Worker error"))},G=()=>{this._worker.removeEventListener("message",O),this._worker.removeEventListener("error",K),clearTimeout(N)};this._worker.addEventListener("message",O),this._worker.addEventListener("error",K),this._worker.postMessage(J)}catch($){Q($)}})}_console(J){console[J.command].apply(console,JSON.parse(J.content))}_onmessage(J){let Z=J.data.target;if(Z==="error"){this._error(J.data.error||"Unknown worker error");return}let Q=this["_"+Z];if(Q)Q.call(this,J.data)}_error(J){let Z=J instanceof Error?J:J instanceof ErrorEvent?J.error||Error(J.message):Error(String(J)),Q=J instanceof Event?new ErrorEvent(J.type,J):new ErrorEvent("error",{error:Z});return this.dispatchEvent(Q),console.error(Z),Z}_removeListeners(){if(this._video){if(this._ro)this._ro.unobserve(this._video);if(this._ctx)this._ctx.filter="none";this._video.removeEventListener("timeupdate",this._boundTimeUpdate),this._video.removeEventListener("progress",this._boundTimeUpdate),this._video.removeEventListener("waiting",this._boundTimeUpdate),this._video.removeEventListener("seeking",this._boundTimeUpdate),this._video.removeEventListener("playing",this._boundTimeUpdate),this._video.removeEventListener("ratechange",this._boundSetRate),this._video.removeEventListener("resize",this._boundResize),this._video.removeEventListener("loadedmetadata",this._boundUpdateColorSpace)}}destroy(J){let Z=J?this._error(J):void 0;if(this._video&&this._canvasParent)this._video.parentNode?.removeChild(this._canvasParent);if(this._gpuRenderer)this._gpuRenderer.destroy(),this._gpuRenderer=null,this._rendererType="canvas2d";return this._destroyed=!0,this._removeListeners(),this.sendMessage("destroy"),this._worker?.terminate(),Z}}export{u as webYCbCrMap,l as testImageBugs,JJ as runFeatureTests,o as parseAss,s as libassYCbCrMap,f as isWebGPUSupported,p as isWebGL2Supported,c as getVideoPosition,r as getColorSpaceFilterUrl,$J as getBitmapBug,ZJ as getAlphaBug,e as fixPlayRes,m as fixAlpha,i as dropBlur,z as default,w as computeCanvasSize,y as colorMatrixConversionMap,v as WebGPURenderer,x as WebGL2Renderer,z as AkariSub};
1
+ /**
2
+ * AkariSub — ASS/SSA subtitle renderer for the browser.
3
+ *
4
+ * Renders libass subtitles with a WebAssembly worker and an optional WebGPU or
5
+ * WebGL2 compositor.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import AkariSub from '@altq/akarisub'
10
+ *
11
+ * const renderer = new AkariSub({
12
+ * video: document.querySelector('video')!,
13
+ * subUrl: '/subtitles/example.ass'
14
+ * })
15
+ *
16
+ * renderer.destroy()
17
+ * ```
18
+ *
19
+ * @module
20
+ */
21
+ export { default } from './wrapper';
22
+ export { default as AkariSub } from './wrapper';
23
+ export { webYCbCrMap, colorMatrixConversionMap, libassYCbCrMap, computeCanvasSize, getVideoPosition, fixAlpha, parseAss, dropBlur, fixPlayRes, testImageBugs, runFeatureTests, getAlphaBug, getBitmapBug, getColorSpaceFilterUrl, getWasmUrl, getWasmGlueUrl, getDefaultFontUrl, WebGPURenderer, isWebGPUSupported, WebGL2Renderer, isWebGL2Supported } from './wrapper';
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,WAAW,CAAA;AAsB/C,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EAClB,MAAM,WAAW,CAAA"}
@@ -0,0 +1,323 @@
1
+ import type { AkariSubOptions, ASSEvent, ASSStyle, PerformanceStats, FrameTimeline } from './types';
2
+ import type { EncryptedSubtitleContent } from './types';
3
+ /**
4
+ * AkariSub - JavaScript ASS/SSA Subtitle Renderer
5
+ *
6
+ * Renders ASS/SSA subtitles on an HTML5 video element using libass compiled to WebAssembly.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const renderer = new AkariSub({
11
+ * video: document.querySelector('video'),
12
+ * subUrl: '/subtitles/example.ass'
13
+ * });
14
+ *
15
+ * // Later, cleanup
16
+ * renderer.destroy();
17
+ * ```
18
+ */
19
+ export default class AkariSub extends EventTarget {
20
+ private static readonly MAX_PENDING_DEMANDS;
21
+ private static readonly MAX_FONT_BYTES;
22
+ private static _hasAlphaBug;
23
+ private static _hasBitmapBug;
24
+ private _loaded;
25
+ private _init;
26
+ private _destroyedSignal;
27
+ private _resolveDestroyed;
28
+ private _pendingWorkerRejectors;
29
+ private _onDemandRender;
30
+ private _offscreenRender;
31
+ private _video?;
32
+ private _videoWidth;
33
+ private _videoHeight;
34
+ private _videoColorSpace;
35
+ private _canvas;
36
+ private _canvasParent?;
37
+ private _bufferCanvas;
38
+ private _bufferCtx;
39
+ private _canvasctrl;
40
+ private _ctx;
41
+ private _lastRenderTime;
42
+ private _playstate;
43
+ private _destroyed;
44
+ private _workerReady;
45
+ private _frameBufferReadyEvent;
46
+ private _ro?;
47
+ private _worker;
48
+ private _pendingDemandTimes;
49
+ private _demandTimings;
50
+ private _adaptiveTiming;
51
+ private _frameTimeline;
52
+ private _preparedFrames;
53
+ private _stagedCanvases;
54
+ private _stageFrameIndices;
55
+ private _stageDisplayTimes;
56
+ private _committedStage;
57
+ private _scheduledPreparedFrame;
58
+ private _predictedDisplayTimes;
59
+ private _displayClockOffsets;
60
+ private _displayGridAnchorMs?;
61
+ private _lastClockMediaTime?;
62
+ private _lastClockPlaybackRate?;
63
+ private _lastPresentedFrameIndex?;
64
+ private _refreshSamples;
65
+ private _refreshRafHandle;
66
+ private _lastRefreshRafTime?;
67
+ private _prepareQueue;
68
+ private _prepareRequests;
69
+ private _nextPrepareId;
70
+ private _prepareForce;
71
+ private _timingCompensationSeconds;
72
+ private _rvfcHandle;
73
+ private _rvfcGeneration;
74
+ private _renderEpoch;
75
+ private _nextDemandId;
76
+ private _nextPresentationId;
77
+ private _latestPresentationId;
78
+ private _nextFontRequestId;
79
+ private readonly _isLikelyWebKit;
80
+ private _boundResize;
81
+ private _boundTimeUpdate;
82
+ private _boundSetRate;
83
+ private _boundUpdateColorSpace;
84
+ private _boundHandleRVFC;
85
+ private _gpuRenderer;
86
+ private _rendererType;
87
+ private _onCanvasFallback?;
88
+ private _lastRenderWidth;
89
+ private _lastRenderHeight;
90
+ private _gpuBitmapImages;
91
+ /** Seconds added to video time when sampling the track. */
92
+ timeOffset: number;
93
+ /** When true, the worker prints libass and renderer logs. */
94
+ debug: boolean;
95
+ /** Extra scale applied to the subtitle canvas before height limits. */
96
+ prescaleFactor: number;
97
+ /** Maximum canvas height that still receives `prescaleFactor`. */
98
+ prescaleHeightLimit: number;
99
+ /** Hard cap on render height; `0` means unlimited. */
100
+ maxRenderHeight: number;
101
+ /** True while the worker is rendering a demand frame. */
102
+ busy: boolean;
103
+ /** Extra seconds of subtitle lookahead on top of adaptive timing. */
104
+ renderAhead: number;
105
+ /** Exact timeline frames to prepare ahead of the playhead. */
106
+ framePrefetch: number;
107
+ /**
108
+ * Create a renderer and start loading the WASM worker.
109
+ *
110
+ * @param options Video or canvas target plus optional fonts and track.
111
+ */
112
+ constructor(options: AkariSubOptions);
113
+ /** @internal */
114
+ private static _testImageBugs;
115
+ /** @internal */
116
+ private static _test;
117
+ /** @internal */
118
+ private static _getSubtitleTransfers;
119
+ /** @internal */
120
+ private _initGPURenderer;
121
+ /** Active compositor: WebGPU, WebGL2, or Canvas2D. */
122
+ get rendererType(): 'webgpu' | 'webgl2' | 'canvas2d';
123
+ /** @deprecated Use rendererType === 'webgpu' */
124
+ get isUsingWebGPU(): boolean;
125
+ /** True when WebGPU or WebGL2 is compositing bitmaps. */
126
+ get isUsingGPURenderer(): boolean;
127
+ /** @internal */
128
+ private _createCanvas;
129
+ /**
130
+ * Resize the overlay canvas.
131
+ *
132
+ * When `width` or `height` is `0` and a video is attached, the overlay is
133
+ * fitted to the letterboxed video rectangle.
134
+ */
135
+ resize(width?: number, height?: number, top?: number, left?: number, force?: boolean): void;
136
+ /** @internal */
137
+ private _timeupdate;
138
+ /** Attach a video element and subscribe to its playback and resize events. */
139
+ setVideo(video: HTMLVideoElement): void;
140
+ /** Fetch and load an ASS/SSA track from `url`. */
141
+ setTrackByUrl(url: string): void;
142
+ /** Replace the current track with ASS/SSA text or bytes. */
143
+ setTrack(content: string | Uint8Array | ArrayBuffer): void;
144
+ /**
145
+ * Overwrites the current subtitle content with encrypted v2 payloads.
146
+ * Decryption happens inside the AkariSub worker so plaintext ASS text is not
147
+ * materialized in the main thread.
148
+ */
149
+ setEncryptedTrack(content: EncryptedSubtitleContent): void;
150
+ /** Unload the current track without destroying the renderer. */
151
+ freeTrack(): void;
152
+ /** Tell the worker whether playback is paused. Ignored when a video element is attached. */
153
+ setIsPaused(isPaused: boolean): void;
154
+ /** Tell the worker the playback rate. Ignored when a video element is attached. */
155
+ setRate(rate: number): void;
156
+ /**
157
+ * Push a manual clock sample to the worker.
158
+ *
159
+ * Omit fields to keep the last known paused state, time, or rate.
160
+ */
161
+ setCurrentTime(isPaused?: boolean, currentTime?: number, rate?: number): void;
162
+ /** Append a Dialogue event to the loaded track. */
163
+ createEvent(event: Partial<ASSEvent>): void;
164
+ /** Overwrite the event at `index`. */
165
+ setEvent(event: Partial<ASSEvent>, index: number): void;
166
+ /** Delete the event at `index`. */
167
+ removeEvent(index: number): void;
168
+ /** Return a snapshot of every event in the loaded track. */
169
+ getEvents(): Promise<ASSEvent[]>;
170
+ /** Force a style onto every event until {@linkcode disableStyleOverride}. */
171
+ styleOverride(style: Partial<ASSStyle>): void;
172
+ /** Clear a style override previously set with {@linkcode styleOverride}. */
173
+ disableStyleOverride(): void;
174
+ /** Append a style to the loaded track. */
175
+ createStyle(style: Partial<ASSStyle>): void;
176
+ /** Overwrite the style at `index`. */
177
+ setStyle(style: Partial<ASSStyle>, index: number): void;
178
+ /** Delete the style at `index`. */
179
+ removeStyle(index: number): void;
180
+ /** Return a snapshot of every style in the loaded track. */
181
+ getStyles(): Promise<ASSStyle[]>;
182
+ /** Register a font URL or file. Fonts larger than 32 MiB are rejected. */
183
+ addFont(font: string | Uint8Array): Promise<void>;
184
+ /** Set the default font family used when a style font is missing. */
185
+ setDefaultFont(font: string): void;
186
+ /** Return renderer throughput and latency counters. */
187
+ getStats(): Promise<PerformanceStats>;
188
+ /** Zero the worker-side performance counters. */
189
+ resetStats(): Promise<void>;
190
+ /**
191
+ * Set encoded video-frame timestamps used to snap live predictions to exact
192
+ * libass sampling times. Pass null to return to continuous-time prediction.
193
+ */
194
+ setFrameTimeline(frameTimes: FrameTimeline | null): void;
195
+ /** Number of events in the loaded track. */
196
+ getEventCount(): Promise<number>;
197
+ /** Number of styles in the loaded track. */
198
+ getStyleCount(): Promise<number>;
199
+ /** @internal */
200
+ private _sendLocalFont;
201
+ /** @internal */
202
+ private _getLocalFont;
203
+ /** @internal */
204
+ private _unbusy;
205
+ /** @internal */
206
+ private _finishWorkerSlot;
207
+ /** @internal */
208
+ private _tryPresentPreparedDemand;
209
+ /** @internal */
210
+ private _dispatchReadyWhenFrameBufferFilled;
211
+ /** @internal */
212
+ private _startRefreshSampling;
213
+ /** @internal */
214
+ private _syncStagedCanvasLayout;
215
+ /** @internal */
216
+ private _releaseGPUStage;
217
+ /** @internal */
218
+ private _removeStagedCanvas;
219
+ /** @internal */
220
+ private _currentExactFrameIndex;
221
+ /** @internal */
222
+ private _currentExactFrameMediaTime;
223
+ /** Make a freshly painted base canvas visible without discarding future prefetch. */
224
+ private _activateBaseCanvas;
225
+ /** @internal */
226
+ private _activateBaseCanvasAfterGPUWork;
227
+ /** @internal */
228
+ private _disposePreparedFrame;
229
+ /** @internal */
230
+ private _stagePreparedFrame;
231
+ /** @internal */
232
+ private _scheduleNextPreparedFrame;
233
+ /** @internal */
234
+ private _commitPreparedStage;
235
+ /** @internal */
236
+ private _schedulePreparedFrame;
237
+ /** @internal */
238
+ private _recordPresentationClock;
239
+ /** @internal */
240
+ private _clearPreparedFrames;
241
+ /** @internal */
242
+ private _primePreparedFrames;
243
+ /** @internal */
244
+ private _dispatchNextPreparation;
245
+ /** @internal */
246
+ private _preparedFrame;
247
+ /** @internal */
248
+ private _presentPreparedFrame;
249
+ /** @internal */
250
+ private _presentedFrame;
251
+ /** @internal */
252
+ private _activatePresentation;
253
+ /** @internal */
254
+ private _bumpRenderEpoch;
255
+ /** @internal */
256
+ private _sendMutatingMessage;
257
+ /** @internal */
258
+ private _cancelRVFC;
259
+ /** @internal */
260
+ private _scheduleRVFC;
261
+ /** @internal */
262
+ private _closeRenderImages;
263
+ /** @internal */
264
+ private _isVideoPausedForWorker;
265
+ /** @internal */
266
+ private _videoPlaybackRateForWorker;
267
+ /** @internal */
268
+ private _setVideoClockStateFromEvent;
269
+ /** @internal */
270
+ private _currentVideoTimeWithOffset;
271
+ /** @internal */
272
+ private _syncVideoClock;
273
+ /** @internal */
274
+ private _requestDemandRender;
275
+ /** @internal */
276
+ private _enqueueDemand;
277
+ /** @internal */
278
+ private _handleRVFC;
279
+ /** @internal */
280
+ private _observeDemandCompletion;
281
+ /** @internal */
282
+ private _demandRender;
283
+ /** @internal */
284
+ private _detachOffscreen;
285
+ /** @internal */
286
+ private _reAttachOffscreen;
287
+ /** @internal */
288
+ private _updateColorSpace;
289
+ /** @internal */
290
+ private _verifyColorSpace;
291
+ /** @internal */
292
+ private _render;
293
+ /** @internal */
294
+ private _renderGPU;
295
+ /** @internal */
296
+ private _ready;
297
+ /** @internal */
298
+ private _partial_ready;
299
+ /** @internal */
300
+ private _trackReady;
301
+ /** Send a raw message to the worker. Prefer the typed methods above. */
302
+ sendMessage(target: string, data?: Record<string, any>, transferable?: Transferable[]): Promise<void>;
303
+ /** @internal */
304
+ private _postWorkerMessage;
305
+ /** @internal */
306
+ private _fetchFromWorker;
307
+ /** @internal */
308
+ private _console;
309
+ /** @internal */
310
+ private _onmessage;
311
+ /** @internal */
312
+ private _error;
313
+ /** @internal */
314
+ private _removeListeners;
315
+ /**
316
+ * Tear down the overlay, GPU renderer, and worker.
317
+ *
318
+ * @param err Optional error to report through the `error` event.
319
+ * @returns The same error object when `err` was passed, otherwise `undefined`.
320
+ */
321
+ destroy(err?: Error | string): Error | undefined;
322
+ }
323
+ //# sourceMappingURL=akarisub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"akarisub.d.ts","sourceRoot":"","sources":["../../src/ts/akarisub.ts"],"names":[],"mappings":"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"}