### 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' }) ```