{"id":19370556,"url":"https://github.com/libass/javascriptsubtitlesoctopus","last_synced_at":"2025-04-07T08:14:19.464Z","repository":{"id":37032077,"uuid":"78491206","full_name":"libass/JavascriptSubtitlesOctopus","owner":"libass","description":"Displays subtitles in .ass format from JavaScript. Supports most SSA/ASS features, easily integrates with HTML5 videos.","archived":false,"fork":false,"pushed_at":"2024-09-11T00:49:55.000Z","size":49115,"stargazers_count":436,"open_issues_count":31,"forks_count":102,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-03-31T07:04:08.230Z","etag":null,"topics":["ass-format","html5-video","javascript","libass","substation-alpha","subtitle-formats","subtitles","video"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/libass.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-10T02:49:47.000Z","updated_at":"2025-03-10T02:29:10.000Z","dependencies_parsed_at":"2024-09-11T04:06:52.175Z","dependency_job_id":null,"html_url":"https://github.com/libass/JavascriptSubtitlesOctopus","commit_stats":{"total_commits":349,"total_committers":15,"mean_commits":"23.266666666666666","dds":0.6504297994269341,"last_synced_commit":"275688aa4f7dca62be7d54bfb5aab767c709cf82"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libass%2FJavascriptSubtitlesOctopus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libass%2FJavascriptSubtitlesOctopus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libass%2FJavascriptSubtitlesOctopus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libass%2FJavascriptSubtitlesOctopus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/libass","download_url":"https://codeload.github.com/libass/JavascriptSubtitlesOctopus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247615377,"owners_count":20967184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ass-format","html5-video","javascript","libass","substation-alpha","subtitle-formats","subtitles","video"],"created_at":"2024-11-10T08:15:57.457Z","updated_at":"2025-04-07T08:14:19.429Z","avatar_url":"https://github.com/libass.png","language":"Python","readme":"[![Actions Status](https://github.com/libass/JavascriptSubtitlesOctopus/actions/workflows/emscripten.yml/badge.svg)](https://github.com/libass/JavascriptSubtitlesOctopus/actions/workflows/emscripten.yml?query=branch%3Amaster+event%3Apush)\n\n\nSubtitlesOctopus displays subtitles in .ass format and easily integrates with HTML5 videos.\nSince it uses [libass](https://github.com/libass/libass), SubtitlesOctopus supports most\nSSA/ASS features and enables you to get consistent results in authoring and web-playback,\nprovided libass is also used locally.\n\n[ONLINE DEMO](https://libass.github.io/JavascriptSubtitlesOctopus/videojs.html)\n/ [other examples with demo](https://libass.github.io/JavascriptSubtitlesOctopus/)\n\n## Features\n\n- Supports most SSA/ASS features (everything libass supports)\n- Supports all OpenType- and TrueType-fonts (including woff2 fonts)\n- Works fast (because uses WebAssembly with fallback to asm.js if it's not available)\n- Uses Web Workers thus video and interface doesn't lag even on \"heavy\" subtitles (working in background)\n- Doesn't use DOM manipulations and render subtitles on single canvas\n- Fully compatible with [libass'](https://github.com/libass/libass) extensions\n  (but beware of compatability to other ASS-renderers when using them)\n- Easy to use - just connect it to video element\n\n## Included Libraries\n\n* libass\n* expat\n* fontconfig\n* freetype\n* fribidi\n* harfbuzz\n* brotli\n\n## Usage\n\nTo start using SubtitlesOctopus you only need to instantiate a new instance of\n`SubtitlesOctopus` and specify its [Options](#options).\n\n```javascript\nvar options = {\n    video: document.getElementById('video'), // HTML5 video element\n    subUrl: '/test/test.ass', // Link to subtitles\n    fonts: ['/test/font-1.ttf', '/test/font-2.ttf'], // Links to fonts (not required, default font already included in build)\n    workerUrl: '/libassjs-worker.js', // Link to WebAssembly-based file \"libassjs-worker.js\"\n    legacyWorkerUrl: '/libassjs-worker-legacy.js' // Link to non-WebAssembly worker\n};\nvar instance = new SubtitlesOctopus(options);\n```\n\nAfter that SubtitlesOctopus automatically \"connects\" to your video and it starts\nto display subtitles. You can use it with any HTML5 player.\n\n[See other examples](https://github.com/libass/JavascriptSubtitlesOctopus/tree/gh-pages/).\n\n### Using only with canvas\nYou're also able to use it without any video. However, that requires you to set\nthe time the subtitles should render at yourself:\n\n```javascript\nvar options = {\n    canvas: document.getElementById('canvas'), // canvas element\n    subUrl: '/test/test.ass', // Link to subtitles\n    fonts: ['/test/font-1.ttf', '/test/font-2.ttf'], // Links to fonts (not required, default font already included in build)\n    workerUrl: '/libassjs-worker.js' // Link to file \"libassjs-worker.js\"\n};\nvar instance = new SubtitlesOctopus(options);\n// And then...\ninstance.setCurrentTime(15); // Render subtitles at 00:15 on your canvas\n```\n\n### Changing subtitles\nYou're not limited to only display the subtitle file you referenced in your\noptions. You're able to dynamically change subtitles on the fly. There's three\nmethods that you can use for this specifically:\n\n- `setTrackByUrl(url)`: works the same as the `subUrl` option. It will set the\n  subtitle to display by its URL.\n- `setTrack(content)`: works the same as the `subContent` option. It will set\n  the subtitle to dispaly by its content.\n- `freeTrack()`: this simply removes the subtitles. You can use the two methods\n  above to set a new subtitle file to be displayed.\n\n```JavaScript\nvar instance = new SubtitlesOctopus(options);\n\n// ... we want to change the subtitles to the Railgun OP\ninstance.setTrackByUrl('/test/railgun_op.ass');\n```\n\n### Cleaning up the object\nAfter you're finished with rendering the subtitles. You need to call the\n`instance.dispose()` method to correctly dispose of the object.\n\n```JavaScript\nvar instance = new SubtitlesOctopus(options);\n\n// After you've finished using it...\n\ninstance.dispose();\n```\n\n\n### Options\nWhen creating an instance of SubtitleOctopus, you can set the following options:\n\n- `video`: The video element to attach listeners to. (Optional)\n- `canvas`: The canvas to render the subtitles to. If none is given it will\n  create a new canvas and insert it as a sibling of the video element (only if\n  the video element exists). (Optional)\n- `subUrl`: The URL of the subtitle file to play. (Require either `subUrl` or\n  `subContent` to be specified)\n- `subContent`: The content of the subtitle file to play. (Require either\n  `subContent` or `subUrl` to be specified)\n- `workerUrl`: The URL of the worker. (Default: `libassjs-worker.js`)\n- `fonts`: An array of links to the fonts used in the subtitle. (Optional)\n- `availableFonts`: Object with all available fonts - Key is font name in lower\n  case, value is link: `{\"arial\": \"/font1.ttf\"}` (Optional)\n- `fallbackFont`: URL to override fallback font, for example, with a CJK one. Default fallback font is Liberation Sans (Optional)\n- `lazyFileLoading`: A boolean, whether to load files in a lazy way via [FS.createLazyFile()](https://emscripten.org/docs/api_reference/Filesystem-API.html#FS.createLazyFile). [Requires](https://github.com/emscripten-core/emscripten/blob/c7b21c32fef92799da05d15ba1939b6394fe0373/src/library_fs.js#L1679-L1856) `Access-Control-Expose-Headers` for `Accept-Ranges, Content-Length, and Content-Encoding`. If encoding is compressed or length is not set, file will be fully fetched instead of just a HEAD request.\n- `timeOffset`: The amount of time the subtitles should be offset from the\n  video. (Default: `0`)\n- `onReady`: Function that's called when SubtitlesOctopus is ready. (Optional)\n- `onError`: Function called in case of critical error meaning the subtitles\n  wouldn't be shown and you should use an alternative method (for instance it\n  occurs if browser doesn't support web workers). (Optional)\n- `debug`: Whether performance info is printed in the console. (Default:\n  `false`)\n- `renderMode`: Rendering mode.\n  (If not set, the deprecated option `lossyRender` is evaluated)\n  - `js-blend` - JS Blending\n  - `wasm-blend` - WASM Blending, currently the default\n  - `lossy` - Lossy Render Mode (EXPERIMENTAL)\n- `targetFps`: Target FPS (Default: `24`)\n- `libassMemoryLimit`: libass bitmap cache memory limit in MiB (approximate)\n                       (Default: `0` - no limit)\n- `libassGlyphLimit`: libass glyph cache memory limit in MiB (approximate)\n                      (Default: `0` - no limit)\n- `prescaleFactor`: Scale down (`\u003c 1.0`) the subtitles canvas to improve\n                    performance at the expense of quality, or scale it up (`\u003e 1.0`).\n                    (Default: `1.0` - no scaling; must be a number \u003e 0)\n- `prescaleHeightLimit`: The height beyond which the subtitles canvas won't be prescaled.\n                         (Default: `1080`)\n- `maxRenderHeight`: The maximum rendering height of the subtitles canvas.\n                     Beyond this subtitles will be upscaled by the browser.\n                     (Default: `0` - no limit)\n- `dropAllAnimations`: If set to true, attempt to discard all animated tags.\n                       Enabling this may severly mangle complex subtitles and\n                       should only be considered as an last ditch effort of uncertain success\n                       for hardware otherwise incapable of displaing anything.\n                       Will not reliably work with manually edited or allocated events.\n                       (Default: `false` - do nothing)\n\n### Rendering Modes\n#### JS Blending\nTo use this mode set `renderMode` to `js-blend` upon instance creation.\nThis will do all the processing of the bitmaps produced by libass outside of WebAssembly.\n\n#### WASM Blending\nTo use this mode set `renderMode` to `wasm-blend` upon instance creation.\nThis will blend the bitmaps of the different events together in WebAssembly,\nso the JavaScript-part only needs to process a single image.\nIf WebAssembly-support is available this will be faster than the default mode,\nespecially for many and/or complex simultaneous subtitles.\nWithout WebAssembly-support it will fallback to asm.js and\nshould at least not be slower than the default mode.\n\n#### Lossy Render Mode (EXPERIMENTAL)\nTo use this mode set `renderMode` to `lossy` upon instance creation.\nThe Lossy Render mode has been created by @no1d as a suggestion for fix browser\nfreezing when rendering heavy subtitles (#46), it uses\n[createImageBitmap](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap)\nto render the bitmap in the Worker, using Promises instead of direct render on\ncanvas in the Main Thread. When the browser start to hang, it will not lock main\nthread, instead will run Async, so if the function createImageBitmap fail, it\nwill not stop the rendering process at all and may cause some bitmap loss or\nsimply will not draw anything in canvas, mostly on low end devices.\n\n**WARNING: Experimental, not stable and not working in some browsers**\n\n\n## How to build?\n\n### Dependencies\n* git\n* emscripten (Configure the enviroment)\n* make\n* python3\n* cmake\n* pkgconfig\n* patch\n* libtool\n* autotools (autoconf, automake, autopoint)\n* gettext\n* ragel - Required by Harfbuzz\n* itstool - Required by Fontconfig\n* python3-ply - Required by WebIDL\n* gperf - Required by Fontconfig\n* licensecheck\n\n### Get the Source\n\nRun `git clone --recursive https://github.com/libass/JavascriptSubtitlesOctopus.git`\n\n### Build inside a Container\n#### Docker\n1) Install Docker\n2) `./run-docker-build.sh`\n3) Artifacts are in /dist/js\n#### Buildah\n1) Install Buildah and a suitable backend for `buildah run` like `crun` or `runc`\n2) `./run-buildah-build.sh`\n3) Artifacts are in /dist/js\n\n### Build without Containers\n1) Install the dependency packages listed above\n2) `make`\n    - If on macOS with libtool from brew, `LIBTOOLIZE=glibtoolize make`\n3) Artifacts are in /dist/js\n\n## Why \"Octopus\"?\nHow am I an Octopus? [Ba da ba da ba!](https://www.youtube.com/watch?v=tOzOD-82mW0)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibass%2Fjavascriptsubtitlesoctopus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibass%2Fjavascriptsubtitlesoctopus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibass%2Fjavascriptsubtitlesoctopus/lists"}