### Rollup Bundler Setup
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Basic Rollup configuration for setting up the project.
```javascript
// rollup.config.js
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
export default {
input: 'src/index.js',
plugins: [
resolve(),
commonjs()
],
output: {
file: 'dist/bundle.js',
format: 'iife'
}
}
```
--------------------------------
### Basic JavaScript Setup
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Initialize JASSUB with a video element and subtitle URL, then wait for readiness.
```javascript
import JASSUB from 'jassub'
// Create instance
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitles/english.ass'
})
// Wait for initialization
await instance.ready
// Subtitles are now rendering automatically
console.log('Subtitles ready!')
// Clean up when done
window.addEventListener('beforeunload', () => {
instance.destroy()
})
```
--------------------------------
### Vite Bundler Setup
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Configuration for Vite to handle WASM assets and worker formats.
```javascript
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
worker: {
format: 'es'
},
assetsInclude: ['**/*.wasm']
})
```
```javascript
import JASSUB from 'jassub'
import workerUrl from 'jassub/dist/jassub-worker.js?worker&url'
import wasmUrl from 'jassub/dist/jassub-worker.wasm?url'
import modernWasmUrl from 'jassub/dist/jassub-worker-modern.wasm?url'
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
workerUrl,
wasmUrl,
modernWasmUrl
})
```
--------------------------------
### TypeScript Type Definitions
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Example demonstrating how to use TypeScript definitions for JASSUB, including importing types and setting up options.
```typescript
import JASSUB from 'jassub'
import type { JASSUBOptions } from 'jassub'
const options: JASSUBOptions = {
video: document.querySelector('video')!,
subUrl: './subtitle.ass',
debug: true
}
const instance = new JASSUB(options)
await instance.ready
```
--------------------------------
### NPM / PNPM / Yarn Installation
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Install JASSUB using your preferred package manager.
```bash
npm install jassub
# or
pnpm add jassub
# or
yarn add jassub
```
--------------------------------
### Scenario 1: Basic Video with Subtitles
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Initialize JASSUB with a video element and a subtitle file URL.
```javascript
import JASSUB from 'jassub'
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass'
})
await instance.ready
```
--------------------------------
### Webpack Bundler Setup
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Configuration for Webpack to handle WASM files and worker assets.
```javascript
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.wasm$/,
type: 'webassembly/async'
},
{
test: /jassub-worker\.js$/,
type: 'asset/resource'
}
]
},
experiments: {
asyncWebAssembly: true
}
}
```
--------------------------------
### Performance Monitoring
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Example demonstrating how to enable debug mode for performance monitoring and display FPS, frame time, and dropped frames.
```javascript
import JASSUB from 'jassub'
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
debug: true // Enable monitoring
})
// Custom dashboard
instance.debug.onsubtitleFrameCallback = (now, metadata) => {
document.getElementById('fps').textContent = metadata.fps.toFixed(1)
document.getElementById('frame-time').textContent = metadata.processingDuration.toFixed(1)
document.getElementById('dropped').textContent = metadata.droppedFrames
}
await instance.ready
```
```html
FPS: 0
| Frame Time: 0ms
| Dropped: 0
```
--------------------------------
### Quality vs Performance Trade-off
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Example showing how to detect device capabilities (mobile, low-end hardware) and adjust JASSUB options for optimization, including memory and glyph limits, and font query settings.
```javascript
import JASSUB from 'jassub'
// Detect device capability and adjust
const isMobile = /iPhone|iPad|Android|Windows Phone/.test(navigator.userAgent)
const isLowEnd = navigator.hardwareConcurrency <= 2
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
// Mobile optimization
prescaleFactor: isMobile ? 0.75 : 1.0,
maxRenderHeight: isLowEnd ? 480 : 1080,
// Memory limits for untrusted input
libassMemoryLimit: 67108864, // 64 MB
libassGlyphLimit: 10000,
// Font queries add complexity
queryFonts: isLowEnd ? false : 'local'
})
await instance.ready
```
--------------------------------
### queryFonts Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Examples demonstrating how to configure the queryFonts option to control font lookup strategies.
```typescript
queryFonts?: 'local' | 'localandremote' | false // Default: 'local'
```
```javascript
// Enable Google Fonts API as last resort
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
queryFonts: 'localandremote', // Query local, then Google Fonts
defaultFont: 'Liberation Sans'
})
// Disable all queries
const instance2 = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
queryFonts: false, // Only use preloaded/availableFonts
defaultFont: 'Arial',
fonts: ['./fonts/Arial.ttf']
})
```
--------------------------------
### Install JASSUB
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Install the library using npm.
```shell
[p]npm i jassub
```
--------------------------------
### Adjusting Subtitle Timing
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Demonstrates how to initialize JASSUB with a specific time offset and how to dynamically adjust it.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
timeOffset: -500 // Adjust in milliseconds
})
```
```javascript
instance.timeOffset = 1000 // Delay by 1 second
```
--------------------------------
### Scenario 2: Multiple Subtitle Tracks
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Initialize JASSUB with a default subtitle track and provide UI elements to switch between different subtitle tracks by URL.
```javascript
import JASSUB from 'jassub'
// Create with first track
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitles/english.ass'
})
await instance.ready
// UI for switching tracks
document.getElementById('switch-spanish').addEventListener('click', async () => {
await instance.renderer.setTrackByUrl('./subtitles/spanish.ass')
})
document.getElementById('switch-french').addEventListener('click', async () => {
await instance.renderer.setTrackByUrl('./subtitles/french.ass')
})
```
--------------------------------
### Prescale Factor Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of using prescaleFactor and prescaleHeightLimit for performance and quality tuning.
```javascript
// 4K monitor with 1080p video
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
prescaleFactor: 0.75, // Render at 810p instead of 1080p
prescaleHeightLimit: 1080
})
```
--------------------------------
### Waiting for Initialization
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Ensures JASSUB is fully initialized before proceeding, which is crucial for operations like subtitle loading.
```javascript
await instance.ready // Wait for initialization
```
--------------------------------
### wasmUrl Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of specifying a custom URL for the non-SIMD WASM fallback.
```typescript
wasmUrl?: string // Default: auto-detected
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
wasmUrl: 'https://cdn.example.com/jassub-worker.wasm'
})
```
--------------------------------
### Handling Font Loading
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Provides a method to test font loading manually and demonstrates initializing JASSUB with a default fallback font.
```javascript
// Test font URL manually
fetch('./fonts/MyFont.woff2')
.then(r => console.log('Font loaded:', r.ok))
.catch(e => console.error('Font load failed:', e))
```
```javascript
// Ensure fallback font is available
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
defaultFont: 'Liberation Sans' // Always available
})
```
--------------------------------
### Subtitle Source from URL
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of initializing JASSUB with a subtitle URL.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitles/english.ass'
})
```
--------------------------------
### Basic HTML Structure
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Minimal HTML structure required for JASSUB integration, including a video element and a container.
```html
JASSUB Example
```
--------------------------------
### Subtitle Source from Content
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of initializing JASSUB with raw subtitle content.
```javascript
const subtitleText = `[Script Info]
Title: My Subtitles
[V4 Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, ...
Style: Default, Arial, 20, &H00FFFFFF, ...
[Events]
Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: Marked=0, 0:00:00.00, 0:00:05.00, Default, , 0, 0, 0, , First subtitle
Dialogue: Marked=0, 0:00:05.00, 0:00:10.00, Default, , 0, 0, 0, , Second subtitle`
const instance = new JASSUB({
video: document.querySelector('video'),
subContent: subtitleText
})
```
--------------------------------
### modernWasmUrl Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of specifying a custom URL for the SIMD WASM version.
```typescript
modernWasmUrl?: string // Default: auto-detected
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
modernWasmUrl: 'https://cdn.example.com/jassub-worker-modern.wasm'
})
```
--------------------------------
### Scenario 3: Bundled Subtitles
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Load subtitle content directly from a string instead of a URL, useful with bundlers. Includes an example Vite configuration.
```javascript
import JASSUB from 'jassub'
import subtitleText from './subtitle.ass?raw'
const instance = new JASSUB({
video: document.querySelector('video'),
subContent: subtitleText // Use raw content instead of URL
})
await instance.ready
```
```javascript
// vite.config.js
export default {
assetsInclude: ['**/*.ass', '**/*.ssa']
}
```
--------------------------------
### debug Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of enabling debug mode for performance monitoring.
```typescript
debug?: boolean // Default: false
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
debug: true
})
instance.debug.onsubtitleFrameCallback = (now, metadata) => {
console.log(`FPS: ${metadata.fps.toFixed(1)}`)
}
```
--------------------------------
### libassMemoryLimit Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of setting a memory limit for the libass library.
```typescript
libassMemoryLimit?: number // Default: 0
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
libassMemoryLimit: 134217728 // 128 MB limit
})
```
--------------------------------
### libassGlyphLimit Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of setting a glyph cache limit for libass.
```typescript
libassGlyphLimit?: number // Default: 0
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
libassGlyphLimit: 10000
})
```
--------------------------------
### setColorMatrix Method Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderers.md
Example usage of the `setColorMatrix` method to handle color space conversions for subtitles and video.
```javascript
// Convert from BT601 subtitles to BT709 video
renderer.setColorMatrix('BT601', 'BT709')
// Use identity matrix (no conversion)
renderer.setColorMatrix()
```
--------------------------------
### workerUrl Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of specifying a custom URL for the jassub-worker.js file.
```typescript
workerUrl?: string // Default: auto-detected from import.meta.url
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
workerUrl: 'https://cdn.example.com/jassub-worker.js'
})
```
--------------------------------
### Type-Safe Renderer Calls
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Illustrates type-safe calls to JASSUB renderer methods, including asynchronous operations and setting properties.
```typescript
// Async calls are automatically Promise-wrapped
const events = await instance.renderer.getEvents()
const styles = await instance.renderer.getStyles()
// Setting properties requires await for proper IPC
await (instance.renderer.useLocalFonts = true)
```
--------------------------------
### JASSUB Constructor Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/jassub.md
Examples demonstrating the usage of the JASSUB constructor with various options.
```javascript
import JASSUB from 'jassub'
// Basic usage with video element
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass'
})
// With custom fonts and performance tuning
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
fonts: [
'./fonts/CustomFont.woff2',
new Uint8Array(fontData)
],
availableFonts: {
'Gandhi Sans': './fonts/GandhiSans-Regular.ttf'
},
prescaleFactor: 0.75,
prescaleHeightLimit: 1080
})
// Canvas-only mode for custom rendering
const instance = new JASSUB({
canvas: document.querySelector('canvas'),
subContent: subtitleString,
debug: true
})
```
--------------------------------
### Video Display Target
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of initializing JASSUB with a video element as the display target.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass'
})
```
--------------------------------
### Optimizing Rendering Performance
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Shows how to reduce CPU usage and prevent dropped frames by adjusting the rendering resolution and setting a maximum render height.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
prescaleFactor: 0.75, // Reduce render resolution
maxRenderHeight: 1080 // Set hard limit
})
```
--------------------------------
### Security Headers for SharedArrayBuffer
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Recommended security headers to enable SharedArrayBuffer for multi-threading. Without these, JASSUB falls back to single-threaded rendering.
```http
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
```
--------------------------------
### createEvent Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Example of creating a new subtitle event with specific properties.
```javascript
await instance.renderer.createEvent({
Start: 1000,
Duration: 5000,
Style: 'Default',
Text: 'New subtitle line',
Layer: 0,
ReadOrder: 0,
MarginL: 0,
MarginR: 0,
MarginV: 0
})
```
--------------------------------
### getEvents Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Example of retrieving subtitle events and logging the text of the first event and the total count.
```javascript
const events = await instance.renderer.getEvents()
console.log(events[0].Text) // First subtitle text
console.log(events.length) // Total subtitle count
```
--------------------------------
### processData Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Example of how to use the processData method to add new subtitle events.
```javascript
await instance.ready
// Add more subtitle events to the current track
await instance.renderer.processData(
'[Events]\n' +
'Dialogue: 0,0:00:10.00,0:00:15.00,Default,,0,0,0,,New subtitle'
)
```
--------------------------------
### WebAssembly Module Initialization Failure Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Demonstrates handling errors when the WASM module fails to load or initialize.
```javascript
try {
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
wasmUrl: 'https://invalid.example.com/wasm' // Will fail
})
await instance.ready
} catch (e) {
console.error('WASM initialization failed:', e)
}
```
--------------------------------
### No Options Provided Error Handling
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Example demonstrating how to handle the 'No options provided' error and the correct way to instantiate JASSUB.
```javascript
try {
const instance = new JASSUB(null) // Wrong
} catch (e) {
if (e.message === 'No options provided') {
console.error('Missing configuration object')
}
}
// Correct
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass'
})
```
--------------------------------
### manualRender Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/jassub.md
Example of manually triggering a subtitle render at a specific video time.
```typescript
const instance = new JASSUB({
canvas: document.querySelector('canvas'),
subUrl: 'subtitle.ass'
})
await instance.ready
// Render at specific time (useful for canvas-only mode)
instance.manualRender({
mediaTime: 10.5,
width: 1920,
height: 1080,
expectedDisplayTime: performance.now()
})
```
--------------------------------
### prescaleHeightLimit Configuration
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of setting the prescaleHeightLimit to cap the render height on high-resolution displays.
```typescript
prescaleHeightLimit?: number // Default: 1080
```
```javascript
// On a 2560x1440 display with 1080p video:
// - Without prescaleHeightLimit: might render at 2160p
// - With prescaleHeightLimit: capped at 1440p (this example)
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
prescaleFactor: 1.0,
prescaleHeightLimit: 1440 // High-res display
})
```
--------------------------------
### Canvas Display Target
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of initializing JASSUB with a canvas element as the display target and manually rendering.
```javascript
const instance = new JASSUB({
canvas: document.querySelector('canvas'),
subUrl: './subtitle.ass'
})
await instance.ready
instance.manualRender({
mediaTime: 10.5,
width: 1920,
height: 1080,
expectedDisplayTime: performance.now()
})
```
--------------------------------
### Basic Usage
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Basic example of initializing JASSUB with a video element and a subtitle URL.
```javascript
import JASSUB from 'jassub'
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './tracks/sub.ass'
})
```
--------------------------------
### useLocalFonts Examples
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Demonstrates checking and enabling the use of local system fonts for subtitles.
```javascript
// Check if local fonts are being used
const enabled = await instance.renderer.useLocalFonts
// Enable local font queries
await (instance.renderer.useLocalFonts = true)
```
--------------------------------
### Color Format Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/types.md
Illustrates how to create color values in packed 32-bit integers, including BGR and RGBA formats with alpha.
```javascript
// Create a red color: &H0000FF (BGR)
const red = 0x0000FF
// Create a semi-transparent red: &H800000FF
const semiTransparent = 0x800000FF
```
--------------------------------
### Install older version for backwards compatibility
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Command to install version 1.8.8 of JASSUB for backwards compatibility with older browser engines.
```shell
[p]npm i jassub@1.8.8
```
--------------------------------
### fonts Configuration
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of using the 'fonts' option to preload an array of font URLs or binary font data.
```typescript
fonts?: Array // Default: []
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
fonts: [
'./fonts/CustomFont.woff2', // URL
'./fonts/AnotherFont.ttf', // URL
new Uint8Array(fontData1), // Binary data
new Uint8Array(fontData2) // Binary data
]
})
```
--------------------------------
### Check for Available Rendering Contexts
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Example of checking browser capabilities for WebGL2, WebGL1, or Canvas2D contexts before initializing JASSUB.
```javascript
// Check before using JASSUB
const canvas = new OffscreenCanvas(100, 100)
const hasWebGL2 = !!canvas.getContext('webgl2')
const hasWebGL1 = !!canvas.getContext('webgl')
const has2D = !!canvas.getContext('2d')
if (!hasWebGL2 && !hasWebGL1 && !has2D) {
console.error('No rendering context available')
// Fallback to text-based subtitles
} else {
// JASSUB can proceed (will auto-select best option)
}
```
--------------------------------
### availableFonts Configuration
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of using availableFonts to map font family names to URLs or binary data for on-demand loading.
```typescript
availableFonts?: Record // Default: {}
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
availableFonts: {
'Gandhi Sans': './fonts/GandhiSans-Regular.ttf',
'Roboto': './fonts/Roboto-Regular.woff2',
'Arial': new Uint8Array(arialFontData),
'Times New Roman': './fonts/TimesNewRoman.ttf'
}
})
```
--------------------------------
### Subtitle Loading Failure Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Demonstrates how to use a try-catch block to handle potential errors during subtitle loading.
```javascript
try {
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './nonexistent.ass' // Will fail
})
await instance.ready
} catch (e) {
console.error('Failed to load subtitles:', e)
}
```
--------------------------------
### addFonts Examples
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Loads and registers fonts for use in subtitles, supporting URLs and binary data.
```javascript
// Load fonts from URLs
await instance.renderer.addFonts([
'./fonts/Arial.woff2',
'./fonts/TimesNewRoman.ttf'
])
// Load from binary data
const fontData = new Uint8Array(/* font bytes */)
await instance.renderer.addFonts([fontData])
// Mix both
await instance.renderer.addFonts([
'./fonts/Font1.woff2',
fontData
])
```
--------------------------------
### Server Configuration for WASM MIME Type
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Examples of how to configure servers to serve WebAssembly files with the correct MIME type.
```javascript
// Node.js / Express
app.use(express.static('.', {
setHeaders: (res, path) => {
if (path.endsWith('.wasm')) {
res.setHeader('Content-Type', 'application/wasm')
}
}
}))
```
```nginx
location ~ \.wasm$ {
add_header Content-Type application/wasm;
}
```
```apache
AddType application/wasm .wasm
```
--------------------------------
### WebAssembly Not Supported Error Handling
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Example of catching the 'WASM not supported' error and providing user feedback.
```javascript
try {
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass'
})
} catch (e) {
if (e.message === 'WASM not supported') {
console.error('This browser does not support WebAssembly')
// Show fallback UI or prompt to upgrade
}
}
```
--------------------------------
### Error Logging Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Demonstrates how errors during font loading or subtitle parsing are logged to the console.
```javascript
// Errors are logged to console.warn
console.warn('Error querying font', fontName, weight, e)
```
--------------------------------
### timeOffset Configuration
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of setting timeOffset to adjust subtitle timing, either advancing or delaying them.
```typescript
timeOffset?: number // Default: 0
```
```javascript
// Subtitles are 500ms late, advance them
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
timeOffset: -500 // Advance by 500ms
})
// Or compensate for video playback delay
await instance.ready
if (videoIsBuffering) {
instance.timeOffset = 1000 // Delay subtitles by 1 second
}
```
--------------------------------
### Explicit Error Handling with JASSUB
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Example of initializing JASSUB with debug mode enabled and handling initialization errors via the `ready` promise.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
timeOffset: 0,
debug: true // Enable logging
})
// Monitor for issues
instance.debug.onsubtitleFrameCallback = (now, meta) => {
if (meta.droppedFrames > 5) {
console.warn('High drop rate, performance degrading')
}
}
// Handle initialization
instance.ready.then(() => {
console.log('Subtitles ready')
}).catch(err => {
console.error('Failed to initialize:', err)
// Show fallback UI
})
```
--------------------------------
### JASSUB Initialization with Time Offset
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/jassub.md
Example of initializing JASSUB with a time offset to delay subtitles.
```javascript
const instance = new JASSUB({
video,
subUrl: 'sub.ass',
timeOffset: 1000 // All subtitles delayed by 1 second
})
console.log(instance.timeOffset) // 1000
```
--------------------------------
### Missing Display Target Error Handling
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/errors.md
Example of handling the 'Missing Display Target' error and correct instantiation with video or canvas.
```javascript
try {
const instance = new JASSUB({
// Missing both video and canvas!
subUrl: './subtitle.ass'
})
} catch (e) {
if (e.message.includes('video or canvas')) {
console.error('No display target (video or canvas) provided')
}
}
// Correct - with video
const instance = new JASSUB({
video: document.querySelector('video'), // ← provides target
subUrl: './subtitle.ass'
})
// Correct - with canvas
const instance = new JASSUB({
canvas: document.querySelector('canvas'), // ← provides target
subUrl: './subtitle.ass'
})
```
```javascript
// Verify element exists before passing
const videoElement = document.querySelector('video')
console.log('Video found:', videoElement !== null)
if (!videoElement) {
console.error('Video element not found in DOM')
}
```
--------------------------------
### Graceful Fallback Error Handling
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Example of implementing a try-catch block to gracefully handle errors during subtitle loading and display a fallback message.
```javascript
import JASSUB from 'jassub'
async function setupSubtitles() {
try {
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass'
})
await instance.ready
return instance
} catch (error) {
console.error('Failed to load subtitles:', error.message)
// Show fallback message
document.querySelector('#subtitles-error').style.display = 'block'
document.querySelector('#subtitles-error').textContent =
'Subtitles unavailable. ' + error.message
return null
}
}
const instance = await setupSubtitles()
```
--------------------------------
### JASSUB Initialization and Ready State
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/jassub.md
Example demonstrating how to initialize JASSUB and wait for the renderer and WebAssembly module to be ready before calling methods.
```javascript
const instance = new JASSUB({ video, subUrl: 'sub.ass' })
await instance.ready
// Now safe to call renderer methods
await instance.renderer.setDefaultFont('Arial')
```
--------------------------------
### Modify Subtitle Styles
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/README.md
Provides examples of getting, modifying, creating, and overriding subtitle styles using the JASSUB renderer.
```javascript
// Get all current styles
const styles = await instance.renderer.getStyles()
// Modify a style
await instance.renderer.setStyle({
Name: 'Default',
FontSize: 28,
PrimaryColour: 0xFFFFFF
}, 0)
// Create a new style
await instance.renderer.createStyle({
Name: 'CustomStyle',
FontName: 'Arial',
FontSize: 20,
PrimaryColour: 0xFF0000,
Bold: 0,
Italic: 0
})
// Override all styles with one
await instance.renderer.styleOverride({
Name: 'Override',
FontName: 'Arial',
FontSize: 24,
PrimaryColour: 0xFFFFFF
})
```
--------------------------------
### Browser Compatibility Check
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
A function to check if the browser supports necessary features like WebAssembly, Workers, Fetch API, and Promises for JASSUB.
```javascript
function canLoadJASSUB() {
const checks = {
wasm: typeof WebAssembly !== 'undefined',
workers: typeof Worker !== 'undefined',
fetch: typeof fetch !== 'undefined',
promise: typeof Promise !== 'undefined'
}
const allSupported = Object.values(checks).every(v => v)
if (!allSupported) {
console.warn('Missing features:', Object.entries(checks)
.filter(([_, v]) => !v)
.map(([k]) => k))
}
return allSupported
}
if (canLoadJASSUB()) {
// Safe to use JASSUB
} else {
// Show fallback UI
}
```
--------------------------------
### Scenario 4: Custom Font Loading
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/getting-started.md
Configure JASSUB to preload custom fonts, specify available fonts for on-demand loading, set a default font, and enable font querying.
```javascript
import JASSUB from 'jassub'
import customFontUrl from './fonts/CustomFont.woff2?url'
import defaultFontUrl from './fonts/Default.ttf?url'
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
// Preload fonts (avoid FOUT)
fonts: [defaultFontUrl],
// Available for on-demand loading
availableFonts: {
'Custom Font': customFontUrl,
'Arial': './fonts/Arial.ttf'
},
// Fallback
defaultFont: 'Default',
// Query fonts if not found
queryFonts: 'localandremote'
})
await instance.ready
```
--------------------------------
### destroy Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/jassub.md
Example of destroying the JASSUB instance to clean up resources.
```typescript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: 'subtitle.ass'
})
// Later, clean up
await instance.destroy()
```
--------------------------------
### Optimized Font Configuration for User Experience
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Recommended configuration for avoiding FOUTs while managing memory and bandwidth efficiently.
```javascript
const instance = new JASSUB({
fonts: fileAttachments // extracted file attachments for the given video, for example MKV's attachments
availableFonts: {
'My Fallback Font Family Name': './fonts/MyFallbackFont.woff2' // or new URL(...).href, only necessary if you want a custom default font, don't include this in fonts[]!
},
defaultFont: 'My Fallback Font Family Name', // optional, only necessary if you want a custom default font
queryFonts: 'localandremote' // optional, local or remote fonts will be queried if a font isn't found in fonts[] or availableFonts and is required for immediate rendering
})
```
--------------------------------
### Custom Bundler Usage
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Example for custom bundlers needing to override worker and WASM URLs.
```javascript
import JASSUB from 'jassub'
import workerUrl from 'jassub/dist/jassub-worker.js?worker&url'
import wasmUrl from 'jassub/dist/jassub-worker.wasm?url' // non-SIMD fallback
import modernWasmUrl from 'jassub/dist/jassub-worker-modern.wasm?url' // SIMD
const instance = new JASSUB({
video: document.querySelector('video'),
subContent: subtitleString,
workerUrl, // you can also use: `new URL('jassub/dist/jassub-worker.js', import.meta.url)` instead of importing it as an url, or whatever solution suits you
wasmUrl,
modernWasmUrl
})
```
--------------------------------
### High Quality (Desktop)
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Configuration focused on high-quality rendering for desktop environments.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
prescaleFactor: 1.5,
prescaleHeightLimit: 2160,
queryFonts: 'localandremote',
debug: true
})
```
--------------------------------
### freeTrack Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Releases all resources associated with the current subtitle track.
```javascript
await instance.renderer.freeTrack()
```
--------------------------------
### Defining Available Fonts with `availableFonts`
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Example of using `availableFonts` to map font names to their sources, supporting various formats and data types.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './tracks/sub.ass',
availableFonts: {
'Gandhi Sans': new URL('./fonts/GandhiSans-Regular.ttf', import.meta.url).href,
'RoBoTO mEdiuM': new Uint8Array(data), // this is quite stupid if you want to conserve resources, since the data will be lingering in memory, but it is supported
'roboto': new URL('./fonts/Roboto-Medium.woff2', import.meta.url).href
}
})
```
--------------------------------
### Pre-loading Fonts with `fonts` option
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Example of pre-loading specific fonts when creating a JASSUB instance.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './tracks/sub.ass',
fonts: [new URL('./fonts/GandhiSans-Regular.woff', import.meta.url).href, new Uint8Array(data)]
})
```
--------------------------------
### setDefaultFont Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Sets the fallback font used when requested fonts are unavailable.
```javascript
await instance.renderer.setDefaultFont('Liberation Sans')
```
--------------------------------
### setTrackByUrl Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Loads and sets a new subtitle track from a given URL.
```javascript
await instance.renderer.setTrackByUrl('./subtitles/english.ass')
```
--------------------------------
### setTrack Example
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderer.md
Replaces the entire subtitle track with new content from a string.
```javascript
const newSubtitles = `[Script Info]
Title: New Subtitles
[V4 Styles]
Format: Name, Fontname, Fontsize...
[Events]
Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,,New subtitle`
await instance.renderer.setTrack(newSubtitles)
```
--------------------------------
### JASSUB Initialization with Debug Enabled
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/jassub.md
Example of initializing JASSUB with debug mode enabled and setting up a callback for subtitle frame events.
```javascript
const instance = new JASSUB({
video,
subUrl: 'sub.ass',
debug: true
})
instance.debug.onsubtitleFrameCallback = (now, metadata) => {
console.log('FPS:', metadata.fps.toFixed(1))
console.log('Dropped frames:', metadata.droppedFrames)
}
```
--------------------------------
### defaultFont Configuration
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/configuration.md
Example of setting defaultFont to specify a fallback font family name.
```typescript
defaultFont?: string // Default: 'liberation sans'
```
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './subtitle.ass',
availableFonts: {
'My Custom Font': './fonts/custom.ttf'
},
defaultFont: 'My Custom Font' // Use custom font as fallback
})
```
--------------------------------
### Canvas2D Renderer: Color Composition
Source: https://github.com/thaunknown/jassub/blob/main/_autodocs/api-reference/renderers.md
Example of color composition logic for the Canvas2D renderer.
```typescript
// For each pixel in the bitmap:
const mask = heap[bitmapPtr + pixelOffset]
const color = bitmap.color // 0xAARRGGBB
const alpha = 1.0 - (color & 0xFF) / 255 // Inverted
const finalAlpha = alpha * mask / 255
// Result pixel in RGBA
const pixel = RGBA(
getRed(color),
getGreen(color),
getBlue(color),
finalAlpha
)
```
--------------------------------
### Enable online font finding
Source: https://github.com/thaunknown/jassub/blob/main/README.md
Example of how to enable online font finding by setting the `queryFonts` option to 'localandremote' when creating a JASSUB instance.
```javascript
const instance = new JASSUB({
video: document.querySelector('video'),
subUrl: './tracks/sub.ass',
queryFonts: 'localandremote'
})
```