akarisub 0.2.1 → 0.2.2
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.
- package/LICENSE +3 -0
- package/README.md +53 -51
- package/THIRD_PARTY_NOTICES.md +1590 -0
- package/dist/COPYRIGHT +1588 -949
- package/dist/akarisub-worker.js +2 -2
- package/dist/akarisub-worker.wasm +0 -0
- package/dist/akarisub.umd.js +3 -3
- package/dist/index.js +3 -3
- package/dist/ts/ts/akarisub.d.ts +0 -4
- package/dist/ts/ts/akarisub.d.ts.map +1 -1
- package/dist/ts/ts/akarisub.js +1 -7
- package/dist/ts/ts/akarisub.js.map +1 -1
- package/dist/ts/ts/types.d.ts +4 -4
- package/dist/ts/ts/types.d.ts.map +1 -1
- package/dist/ts/ts/webgl2-renderer.d.ts +2 -1
- package/dist/ts/ts/webgl2-renderer.d.ts.map +1 -1
- package/dist/ts/ts/webgl2-renderer.js +19 -16
- package/dist/ts/ts/webgl2-renderer.js.map +1 -1
- package/dist/ts/ts/webgpu-renderer.d.ts +2 -4
- package/dist/ts/ts/webgpu-renderer.d.ts.map +1 -1
- package/dist/ts/ts/webgpu-renderer.js +19 -52
- package/dist/ts/ts/webgpu-renderer.js.map +1 -1
- package/dist/ts/ts/worker.js +120 -53
- package/dist/ts/ts/worker.js.map +1 -1
- package/package.json +3 -1
- package/src/ts/akarisub.ts +2 -8
- package/src/ts/types.ts +4 -3
- package/src/ts/webgl2-renderer.ts +19 -13
- package/src/ts/webgpu-renderer.ts +26 -71
- package/src/ts/worker.ts +126 -47
package/LICENSE
CHANGED
|
@@ -21,3 +21,6 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
21
21
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
22
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
23
|
SOFTWARE.
|
|
24
|
+
|
|
25
|
+
Third-party components and bundled assets are licensed separately. See
|
|
26
|
+
THIRD_PARTY_NOTICES.md, also shipped as dist/COPYRIGHT, for dependency notices.
|
package/README.md
CHANGED
|
@@ -25,9 +25,10 @@ AkariSub is a JS wrapper for <a href="https://github.com/libass/libass">libass</
|
|
|
25
25
|
|
|
26
26
|
### Fork Enhancements
|
|
27
27
|
|
|
28
|
-
- **
|
|
28
|
+
- **GPU Rendering** - Hardware-accelerated rendering with an automatic fallback chain: WebGPU [(on browsers which support it)](https://caniuse.com/webgpu) → WebGL2 → Canvas2D
|
|
29
29
|
- **Hyper Optimizations** - Performance improvements and intelligent caching for smoother playback
|
|
30
30
|
- **Proper Fontconfig Implementation** - add Fontconfig support with multiple fallback fonts supported
|
|
31
|
+
- **Encrypted Subtitles** - optionally load AES-GCM encrypted subtitle payloads that are decrypted inside the worker, so plaintext never touches the main thread
|
|
31
32
|
- **Statistics Reporting** - Built-in statistics and performance metrics for debugging and monitoring
|
|
32
33
|
- **TypeScript Support** - Full TypeScript definitions and type safety
|
|
33
34
|
- **Updated Dependencies** - All dependencies updated to their latest versions, including libass
|
|
@@ -51,7 +52,7 @@ deno add jsr:@altq/akarisub
|
|
|
51
52
|
By default all you need to do is copy the files from the `dist/` folder of the repository into the same folder as where your JS runs, then do:
|
|
52
53
|
|
|
53
54
|
```js
|
|
54
|
-
import AkariSub from './
|
|
55
|
+
import AkariSub from './index.js'
|
|
55
56
|
|
|
56
57
|
const renderer = new AkariSub({
|
|
57
58
|
video: document.querySelector('video'),
|
|
@@ -78,26 +79,29 @@ const renderer = new AkariSub({
|
|
|
78
79
|
|
|
79
80
|
## Using only with canvas
|
|
80
81
|
|
|
81
|
-
You're also able to use it without any video. However, that requires you to set the time the subtitles should render at yourself:
|
|
82
|
+
You're also able to use it without any video. However, that requires you to set the time the subtitles should render at yourself. Disable `onDemandRender` (it relies on video frame callbacks) and drive the clock manually:
|
|
82
83
|
|
|
83
84
|
```js
|
|
84
|
-
import AkariSub from './
|
|
85
|
+
import AkariSub from './index.js'
|
|
85
86
|
|
|
86
87
|
const renderer = new AkariSub({
|
|
87
88
|
canvas: document.querySelector('canvas'),
|
|
88
|
-
subUrl: './tracks/sub.ass'
|
|
89
|
+
subUrl: './tracks/sub.ass',
|
|
90
|
+
onDemandRender: false
|
|
89
91
|
})
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
// setCurrentTime(isPaused?, currentTime?, rate?)
|
|
94
|
+
renderer.setCurrentTime(true, 15)
|
|
92
95
|
```
|
|
93
96
|
|
|
94
97
|
## Changing subtitles
|
|
95
98
|
|
|
96
|
-
You're not limited to only display the subtitle file you referenced in your options. You're able to dynamically change subtitles on the fly. There's
|
|
99
|
+
You're not limited to only display the subtitle file you referenced in your options. You're able to dynamically change subtitles on the fly. There's four methods that you can use for this specifically:
|
|
97
100
|
|
|
98
101
|
- `setTrackByUrl(url):` works the same as the `subUrl` option. It will set the subtitle to display by its URL.
|
|
99
|
-
- `setTrack(content):` works the same as the `subContent` option. It will set the subtitle to display by its content.
|
|
100
|
-
- `
|
|
102
|
+
- `setTrack(content):` works the same as the `subContent` option. It will set the subtitle to display by its content (string, `Uint8Array` or `ArrayBuffer`).
|
|
103
|
+
- `setEncryptedTrack(content):` works the same as the `encryptedSubContent` option. The payload is decrypted inside the worker, so plaintext subtitles are never materialized on the main thread.
|
|
104
|
+
- `freeTrack():` this simply removes the subtitles. You can use the methods above to set a new subtitle file to be displayed.
|
|
101
105
|
|
|
102
106
|
```js
|
|
103
107
|
renderer.setTrackByUrl('/newsub.ass')
|
|
@@ -168,9 +172,9 @@ console.log(`Events: ${eventCount}, Styles: ${styleCount}`)
|
|
|
168
172
|
| `cacheHits` | number | Number of cache hits (unchanged frames) |
|
|
169
173
|
| `cacheMisses` | number | Number of cache misses (rendered frames) |
|
|
170
174
|
|
|
171
|
-
##
|
|
175
|
+
## GPU Rendering
|
|
172
176
|
|
|
173
|
-
AkariSub automatically
|
|
177
|
+
AkariSub automatically picks the fastest available renderer: WebGPU → WebGL2 → Canvas2D. GPU renderers are used when no custom canvas is given and the browser supports them:
|
|
174
178
|
|
|
175
179
|
```typescript
|
|
176
180
|
import AkariSub from 'akarisub'
|
|
@@ -178,14 +182,14 @@ import AkariSub from 'akarisub'
|
|
|
178
182
|
const renderer = new AkariSub({
|
|
179
183
|
video: document.querySelector('video'),
|
|
180
184
|
subUrl: './tracks/sub.ass',
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
console.log('WebGPU unavailable, using Canvas2D fallback')
|
|
185
|
+
onCanvasFallback: () => {
|
|
186
|
+
console.log('No GPU renderer available, using Canvas2D fallback')
|
|
184
187
|
}
|
|
185
188
|
})
|
|
186
189
|
|
|
187
|
-
//
|
|
188
|
-
|
|
190
|
+
console.log(renderer.rendererType) // 'webgpu' | 'webgl2' | 'canvas2d'
|
|
191
|
+
|
|
192
|
+
if (renderer.isUsingGPURenderer) {
|
|
189
193
|
console.log('GPU-accelerated rendering enabled!')
|
|
190
194
|
}
|
|
191
195
|
```
|
|
@@ -199,7 +203,7 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
199
203
|
| `video` | HTMLVideoElement | - | Video to use as target for rendering and event listeners |
|
|
200
204
|
| `canvas` | HTMLCanvasElement | - | Canvas to use for manual handling (optional if video is provided) |
|
|
201
205
|
| `blendMode` | `'js'` \| `'wasm'` | `'wasm'` | Image blending mode. WASM is better for low-end devices, JS for hardware acceleration |
|
|
202
|
-
| `asyncRender` | boolean | `true`
|
|
206
|
+
| `asyncRender` | boolean | auto | Render via ImageBitmap. Defaults to `true` on Canvas2D paths and `false` when a GPU renderer is active (raw buffers upload with fewer copies) or on WebKit |
|
|
203
207
|
| `offscreenRender` | boolean | `true` | Render fully on the worker, greatly reduces CPU usage |
|
|
204
208
|
| `onDemandRender` | boolean | `true` | Render subtitles as the video player renders frames |
|
|
205
209
|
| `targetFps` | number | `24` | Target FPS when not using onDemandRender |
|
|
@@ -211,18 +215,20 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
211
215
|
| `dropAllAnimations` | boolean | `false` | Discard all animated tags for performance |
|
|
212
216
|
| `dropAllBlur` | boolean | `false` | Drop all blur effects (~10x performance gain) |
|
|
213
217
|
| `clampPos` | boolean | `false` | Clamp `\pos` values to script resolution |
|
|
218
|
+
| `renderAhead` | number | `0.008` | Extra seconds to render ahead, compensates pipeline latency |
|
|
214
219
|
| `workerUrl` | string | `'akarisub-worker.js'` | URL to the worker script |
|
|
215
220
|
| `wasmUrl` | string | `'akarisub-worker.wasm'` | URL to the WASM binary |
|
|
216
221
|
| `subUrl` | string | - | URL of the subtitle file to play |
|
|
217
|
-
| `subContent` | string | - | Content of the subtitle file to play |
|
|
222
|
+
| `subContent` | string \| Uint8Array \| ArrayBuffer | - | Content of the subtitle file to play |
|
|
223
|
+
| `encryptedSubContent` | EncryptedSubtitleContent | - | AES-GCM encrypted subtitle payload, decrypted inside the worker |
|
|
218
224
|
| `fonts` | (string \| Uint8Array)[] | - | Array of font URLs or Uint8Arrays to force load |
|
|
219
225
|
| `availableFonts` | Record<string, string \| Uint8Array> | `{'liberation sans': './default.woff2'}` | Available fonts map (lowercase name → URL/data) |
|
|
220
|
-
| `
|
|
221
|
-
| `useLocalFonts` | boolean | `
|
|
222
|
-
| `libassMemoryLimit` | number |
|
|
223
|
-
| `libassGlyphLimit` | number |
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
+
| `fallbackFonts` | string[] | `['liberation sans']` | Fallback font families in order, used for the fontconfig cascade |
|
|
227
|
+
| `useLocalFonts` | boolean | `true` | Use Local Font Access API if available |
|
|
228
|
+
| `libassMemoryLimit` | number | `128` | libass bitmap cache memory limit in MiB |
|
|
229
|
+
| `libassGlyphLimit` | number | `2048` | libass glyph cache limit |
|
|
230
|
+
| `fullTrackWarmup` | boolean | `false` | Pre-render early track windows after load to warm libass caches |
|
|
231
|
+
| `onCanvasFallback` | function | - | Callback when no GPU renderer is available (Canvas2D fallback) |
|
|
226
232
|
|
|
227
233
|
## Methods
|
|
228
234
|
|
|
@@ -231,7 +237,8 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
231
237
|
| Method | Parameters | Description |
|
|
232
238
|
|--------|------------|-------------|
|
|
233
239
|
| `setTrackByUrl(url)` | `url: string` | Load subtitle from URL |
|
|
234
|
-
| `setTrack(content)` | `content: string` | Set subtitle from
|
|
240
|
+
| `setTrack(content)` | `content: string \| Uint8Array \| ArrayBuffer` | Set subtitle from content |
|
|
241
|
+
| `setEncryptedTrack(content)` | `content: EncryptedSubtitleContent` | Set subtitle from an encrypted payload (decrypted in the worker) |
|
|
235
242
|
| `freeTrack()` | - | Remove current subtitles |
|
|
236
243
|
|
|
237
244
|
### Playback Control
|
|
@@ -286,7 +293,6 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
286
293
|
| `resetStats()` | - | `Promise<void>` | Reset statistics counters |
|
|
287
294
|
| `getEventCount()` | - | `Promise<number>` | Get event count (lightweight) |
|
|
288
295
|
| `getStyleCount()` | - | `Promise<number>` | Get style count (lightweight) |
|
|
289
|
-
| `runBenchmark()` | - | `void` | Run a benchmark on the worker |
|
|
290
296
|
|
|
291
297
|
### Lifecycle
|
|
292
298
|
|
|
@@ -304,8 +310,11 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
304
310
|
| `prescaleHeightLimit` | number | Height limit for prescaling |
|
|
305
311
|
| `maxRenderHeight` | number | Maximum render height |
|
|
306
312
|
| `timeOffset` | number | Subtitle time offset in seconds |
|
|
313
|
+
| `renderAhead` | number | Extra seconds to render ahead of the video clock |
|
|
307
314
|
| `busy` | boolean | Whether the renderer is currently busy |
|
|
308
|
-
| `
|
|
315
|
+
| `rendererType` | `'webgpu'` \| `'webgl2'` \| `'canvas2d'` | Active renderer backend (read-only) |
|
|
316
|
+
| `isUsingGPURenderer` | boolean | Whether a hardware-accelerated renderer is active (read-only) |
|
|
317
|
+
| `isUsingWebGPU` | boolean | *Deprecated* - use `rendererType === 'webgpu'` |
|
|
309
318
|
|
|
310
319
|
## Type Definitions
|
|
311
320
|
|
|
@@ -313,8 +322,8 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
313
322
|
|
|
314
323
|
| Property | Type | Description |
|
|
315
324
|
|----------|------|-------------|
|
|
316
|
-
| `Start` | number | Start time in
|
|
317
|
-
| `Duration` | number | Duration in
|
|
325
|
+
| `Start` | number | Start time in milliseconds |
|
|
326
|
+
| `Duration` | number | Duration in milliseconds |
|
|
318
327
|
| `Style` | string | Style name |
|
|
319
328
|
| `Name` | string | Character name (informational) |
|
|
320
329
|
| `MarginL` | number | Left margin override in pixels |
|
|
@@ -361,11 +370,11 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
361
370
|
|
|
362
371
|
## Dependencies
|
|
363
372
|
|
|
373
|
+
[mise](https://mise.jdx.dev) manages the toolchain (emsdk, bun, cmake — see `mise.toml`). You additionally need the usual autotools build dependencies:
|
|
374
|
+
|
|
364
375
|
- git
|
|
365
|
-
- emscripten (Configure the enviroment)
|
|
366
376
|
- make
|
|
367
377
|
- python3
|
|
368
|
-
- cmake
|
|
369
378
|
- pkgconfig
|
|
370
379
|
- patch
|
|
371
380
|
- libtool
|
|
@@ -374,29 +383,22 @@ The default options are best, and automatically fallback to the next fastest opt
|
|
|
374
383
|
- ragel - Required by Harfbuzz
|
|
375
384
|
- itstool - Required by Fontconfig
|
|
376
385
|
- gperf - Required by Fontconfig
|
|
377
|
-
- licensecheck
|
|
378
386
|
|
|
379
387
|
## Get the Source
|
|
380
388
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
### Docker
|
|
386
|
-
|
|
387
|
-
1. Install Docker
|
|
388
|
-
2. ./run-docker-build.sh
|
|
389
|
-
3. Artifacts are in /dist/js
|
|
390
|
-
|
|
391
|
-
### Buildah
|
|
389
|
+
```bash
|
|
390
|
+
git clone --recursive https://github.com/altqx/akarisub.git
|
|
391
|
+
```
|
|
392
392
|
|
|
393
|
-
|
|
394
|
-
2. ./run-buildah-build.sh
|
|
395
|
-
3. Artifacts are in /dist/js
|
|
393
|
+
## Build
|
|
396
394
|
|
|
397
|
-
|
|
395
|
+
```bash
|
|
396
|
+
mise install # installs emsdk, bun, cmake
|
|
397
|
+
bun install # JS dependencies
|
|
398
|
+
make # builds the static libs (fribidi, freetype, harfbuzz, fontconfig, libass, ...) and the WASM worker
|
|
399
|
+
bun run build # builds the WASM worker, TypeScript declarations and JS bundles
|
|
400
|
+
```
|
|
398
401
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
3. Artifacts are in /dist/js
|
|
402
|
+
- If on macOS with libtool from brew, `LIBTOOLIZE=glibtoolize make`
|
|
403
|
+
- Incremental rebuilds of the worker only: `bun run build:wasm` (or `make worker`)
|
|
404
|
+
- Artifacts are in `dist/`
|