Arnavion / libjass

Renders ASS subs in the browser.
Apache License 2.0
174 stars 29 forks source link

This project is no longer being worked on.

You should probably use something else, like https://github.com/Dador/JavascriptSubtitlesOctopus

When I started libjass in 2011, I made a bet that offloading rendering to the DOM would eventually be the way to get fast and accurate rendering. CSS filter effects were about to be standardized. Regular JavaScript would've been too slow to do the fancy rendering that ASS requires. Surely letting the browser render text would be faster than parsing fonts in JS, computing the dimensions and margins for every rendered character, and blitting individual outline and shadow pixels to a canvas.

However CSS filter effects by themselves turned out to be inadequate to accurately render even the basics of ASS. SVG filters are more accurate, but are unoptimized or unsupported in all browsers since nobody really uses them (a vicious cycle). As such, both of them are unable to efficiently render the simplest and most common ASS feature - the elliptical border. The feMorphology SVG filter can only dilate to rectangles, so libjass has to stack many such rectangles of different sizes to approximate an ellipse. Big borders end up needing tens of such rectangles and a large gaussian blur, which brings even the mightiest browser's renderer to its single-threaded knees.

Layout also has problems. CSS doesn't provide an easy to way for a subtitle to push another subtitle away so that they don't overlap. It doesn't provide a line-breaking strategy that tries to equalize the lengths of the broken lines (what ASS calls smart line wrapping). Vertically centering things is still a nightmare - flexbox and CSS grid don't help because subtitles don't follow grids - so \an4-6 were never properly implemented. These things could be solved by positioning the text manually, but this would've brought us back to the problem of parsing fonts and measuring text dimensions in JavaScript instead of letting the DOM handle it.

In 2013, asm.js became a way to use the original C renderers like libass, compiled to something that's not as fast as native C but still faster than regular JavaScript rendering. More recently, WASM has emerged as a more cross-platform and strongly-guaranteed way of doing this. Parsing fonts and computing dimensions is now a feasible prospect.

Because of this, I believe libjass's strategy of relying on the browser DOM is a dead end.

I'm happy to continue providing support and answering questions about the code on Github. Since this repository is archived, please ask by opening an issue at https://github.com/Arnavion/archived-repos-issues instead. The code in this repository is still available under APL-2.0. The ASS parser is functional regardless of the browser renderer. Feel free to fork this project, or incorporate its code into your own projects, under the terms of the license.

Thank you, the users who used libjass on your websites, opened issues, and contributed fixes. libjass was my first OSS project that I intended to be used by more people than me. I had fun working on it and learning about web dev.


libjass is a JavaScript library written in TypeScript to render ASS subs in the browser. Check out the demo.

What's special about libjass?

As a result, libjass is able to render subtitles with very low CPU usage. The downside to libjass's aproach is that it is hard (and potentially impossible) to map all effects possible in ASS (using \t, ASS draw) etc. into DOM elements. As of now, the subset of tags supported by libjass has no such problems.

I want to use libjass for my website. What do I need to do?

You can install the latest release of libjass

Inside the package, you will find libjass.js and libjass.css, which you need to load on your website with your video.

Alternatively, you can build libjass from source by cloning this repository and running npm install. This will install the dependencies and run the build. libjass.js and libjass.css will be found in the lib/ directory.

Only libjass.js and libjass.css are needed to use libjass on your website. The other files are only used during the build process and you don't need to deploy them to your website.

What are all these files?

How do I use libjass?

The API documentation is linked in the Links section below. Here's an overview:

What browser and JavaScript features does libjass need?

Can I use libjass in node?

libjass's parser works in node. Entire scripts can be parsed via ASS.fromString()

> var libjass = require("libjass")
undefined
> var ass; libjass.ASS.fromString(fs.readFileSync("mysubs.ass", "utf8")).then(function (result) { ass = result; })
{}
> ass.properties.resolutionX
1280
> ass.dialogues.length
9
> ass.dialogues[0].toString()
'#0 [646.460-652.130] {\\fad(200,0)}Sapien rhoncus, suscipit posuere in nunc pellentesque'
> var parts = ass.dialogues[0].parts
undefined
> parts.length
2
> parts[0] instanceof libjass.parts.Fade
true
> parts[0].toString()
'Fade { start: 0.2, end: 0 }'

libjass.parser.parse parses the first parameter using the second parameter as the rule name. For example, the dialogueParts rule can be used to get an array of libjass.parts objects that represent the parts of an ASS dialogue line.

> var parts = libjass.parser.parse("{\\an8}Are {\\i1}you{\\i0} the one who stole the clock?!", "dialogueParts")
undefined
> parts.join(" ")
'Alignment { value: 8 } Text { value: Are  } Italic { value: true } Text { value: you } Italic { value: false } Text { value:  the one who stole the clock?! }'
> parts.length
6
> parts[0].toString()
'Alignment { value: 8 }'
> parts[0] instanceof libjass.parts.Alignment
true
> parts[0].value
8

The rule names are derived from the methods on the ParserRun class.

See the tests, particularly the ones in tests/unit/miscellaneous.js, for examples.

Supported features

Known issues

Links

License

libjass

https://github.com/Arnavion/libjass

Copyright 2013 Arnav Singh

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.