Giter Club home page Giter Club logo

libjass's Introduction

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?

  • libjass requires no tweaks to the ASS file from the original video.

  • libjass uses the browser's native CSS engine by converting the components of each line in the ASS script into a series of styled <div> and <span> elements. This allows all the layout and rendering to be handled by the browser instead of requiring complex and costly drawing and animation code. For example, libjass uses CSS3 animations to simulate tags such as \fad. While a canvas-drawing library would have to re-draw such a subtitle on the canvas for every frame of the video, libjass only renders it once and lets the browser render the fade effect.

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

  • using npm with npm install libjass and load with var libjass = require("libjass");
  • using bower with bower install https://github.com/Arnavion/libjass/releases/download/<release name>/libjass.zip
  • using jspm with jspm install github:Arnavion/libjass and load with import libjass from "Arnavion/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?

  • The src/ directory contains the source of libjass. They are TypeScript files and get compiled into JavaScript for the browser using the TypeScript compiler.

  • build.js is the build script. The build command will use this script to build libjass.js. The build/ directory contains other files used for the build.

  • The tests/ directory contains unit and functional tests.

  • The lib/ directory contains libjass.js and libjass.css. You will need to deploy these to your website.

How do I use libjass?

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

  • The ASS.fromUrl() function takes in a URL to an ASS script and returns a promise that resolves to an ASS object. This ASS object represents the script properties, the line styles and dialogue lines in it. Alternatively, you can use ASS.fromString() to convert a string of the script contents into an ASS object.

  • Next, you initialize a renderer to render the subtitles. libjass ships with an easy-to-use renderer, the DefaultRenderer. It uses information from the ASS object to build up a series of div elements around the video tag. There is a wrapper (.libjass-subs) containing div's corresponding to the layers in the ASS script, and each layer has div's corresponding to the 9 alignment directions. libjass.css contains styles for these div's to render them at the correct location.

  • The renderer uses window.requestAnimationFrame as a source of timer ticks. In each tick, it determines the set of dialogues to be shown at the current video time, renders each of them as a div, and appendChild's the div into the appropriate layer+alignment div.

  • The renderer can be told to dynamically change the size of the subtitles based on user input by calling WebRenderer.resize()

  • Lastly, the renderer contains an implementation of preloading fonts before playing the video. It uses a map of font names to URLs - this map can be conveniently created from a CSS file containing @font-face rules using RendererSettings.makeFontMapFromStyleElement()

  • For an example of using libjass, check out the demo. It has comments explaining basic usage and pointers to some advanced usage.

What browser and JavaScript features does libjass need?

  • libjass uses some ES5 features like getters and setters (via Object.defineProperty), and assumptions like the behavior of parseInt with leading zeros. It cannot be used with an ES3 environment.

  • libjass will use ES6 Set, Map and Promise if they're available on the global object. If they're not present, it will use its own minimal internal implementations. If you have implementations of these that you would like libjass to use but don't want to register them on the global object, you can provide them to libjass specifically by setting the libjass.Set, libjass.Map and libjass.Promise properties.

  • AutoClock and VideoClock use window.requestAnimationFrame to generate clock ticks.

  • WebRenderer and DefaultRenderer use SVG filter effects for HTML to render outlines and blur. This feature is not available on all browsers, so you can tell them to fall back to more widely available CSS methods by setting the RendererSettings.enableSvg property to false.

  • WebRenderer and DefaultRenderer use CSS3 animations for effects like \mov and \fad.

  • Using fonts attached to the script requires ES6 typed arrays (ArrayBuffer, DataView, Uint8Array, etc).

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

  • Styles: Italic, Bold, Underline, StrikeOut, FontName, FontSize, ScaleX, ScaleY, Spacing, PrimaryColor, OutlineColor, BackColor, Outline, Shadow, Alignment, MarginL, MarginR, MarginV
  • Tags: \i, \b, \u, \s, \bord, \xbord, \ybord, \shad, \xshad, \yshad, \be, \blur, \fn, \fs, \fscx, \fscy, \fsp, \frx, \fry, \frz, \fr, \fax, \fay, \c, \1c, \3c, \4c, \alpha, \1a, \3a, \4a, \an, \a, \k, \q, \r, \pos, \move, \fad, \fade, \t (experimental), \p
  • Custom fonts, using CSS web fonts.

Known issues

  • Unsupported tags: \fe, \2c, \2a, \K, \kf, \ko, \org, \clip, \iclip
  • \an4, \an5, \an6 aren't positioned correctly.
  • Smart line wrapping is not supported. Such lines are rendered as wrapping style 1 (end-of-line wrapping).
  • Lines with multiple rotations aren't rotated the same as VSFilter or libass. See #14
  • Desktop renderers include borders when calculating space between adjacent lines. libjass doesn't.

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.

libjass's People

Contributors

arnavion avatar dador avatar doomtay avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libjass's Issues

Animated \alpha start animation from 0% opacity

Animated \alpha start animation from 0% opacity while should start it from 100% opacity.

Test script:

[Script Info]
Title:
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 1,0:00:00.00,0:00:36.95,Default,,0,0,0,,{\t(2000,5000,\alpha&7E&)}test

Font scale (\fscx, \fscy) is wrong (bigger than should be)

Seems like proportion is right but whole text becomes much bigger than should be.

In libjass:
libjass-1

In Aegisub (libass):
libass

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:10:00.00,Default,,0,0,0,,{\fscx50}xxxxxxxxxxxxxxxxx
Dialogue: 0,0:00:00.50,0:10:00.00,Default,,0,0,0,,{\fscy50}yyyyyyyyyyyyyyyyy

Clock ticks don't update animations when paused

With a paused clock, animations are paused. WebRenderer.draw is a no-op because the dialogue is already drawn. As a result, the sub animation remains paused at the frame it was first drawn at instead of updating with the ticks.

Margins should be shared between multiple subs in same alignment group

In libjass:
2015-08-01_21-28-50

In Aegisub (libass):
25_001_0

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on bottom 1
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on top 1

P.S. Test almost the same as #49 but this issue about different thing so I decided to put it in separate issue.

Timing out of sync after network lag or heavy animation

Happens often when playing video with heavy animation (heavy for libjass, fine in native player). Also that happens on regural subtitles on mobile devices (such as Chrome on Android tablet). In case of network lag (html5 player waiting for video to load) that happens too.

These delays started after implementing new AutoClock. AutoClock take value of currentTime from html5 video only once. So difference between time in AutoClock and currentTime in html5 video growing and growing. Re-sync of timing happens only if seek to other part of video. It doesn't happens on play & pause.

Maybe sync time each "onupdatetime" event? (but there may be noticeable gaps, not sure)
BTW, why you decided to switch from "onupdatetime" to manual clock only?

Wrong order of dialogues

In libjass:
2015-08-01_21-28-50

In Aegisub (libass):
25_001_0

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on bottom 1
Dialogue: 0,0:00:00.00,0:00:03.00,Default,,0,0,0,,Should be on top 1
Dialogue: 0,0:00:04.00,0:10:00.00,Default,,0,0,0,,Should be on bottom 2
Dialogue: 0,0:00:05.00,0:10:00.00,Default,,0,0,0,,Should be on top 2

P.S. Test almost the same as #48 but this issue about different thing so I decided to put it in separate issue.

Renderer tests

  • A renderer decoupled from <video> - WebRenderer
  • A clock decoupled from <video> - ManualClock
  • A test framework that can load a minimal page with libjass.js, a single div, and the test JS, then take screenshots.

Possible to render ASS before ASS.fromURL promise is fully resolved?

My use case is I use torrent-stream, which creates readable streams of torrent files. You can start watching video files, before they are fully transferred. I can also feed a mkv video file stream into ffmpeg to create a ASS file stream. It would be neat if libjass could support rendering the currently parsed dialogue.

I looked around and it seems like I could create my own versions of ASS.fromURL & ASS.fromStream to return the minimalAss promise instead. I didn't see if using that would work yet and the renderer was too complex to figure out for me for now.

Anyways, if libjass could support this use case that would be super. If modified ASS.fromURL & ASS.fromStream is all that's needed for it to work, I'll send a pull request.

Newlines don't work depending on… something

This works:

[Script Info]
; Script generated by FFmpeg/Lavc56.12.100
ScriptType: v4.00+
PlayResX: 384
PlayResY: 288

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,2,10,10,10,0

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:02.96,0:00:06.40,Default,,0,0,0,,That's my vehicle\Nand I want it back!

This does not:

[Script Info]
ScriptType: v4.00+
PlayResX: 384
PlayResY: 288

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding
Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,1,1,0,2,10,10,10,0,0

[Events]
Format: Layer, Start, End, Style, Text
Dialogue: 0,0:00:02.88,0:00:06.32,Default,That's my vehicle\Nand I want it back!

It produces output like this:
It looks like a number of style attributes don't output.

Manual clock behavior weird

Calling this.disable() first sets this._enabled to false, then calls this.pause() which does nothing because this._enabled is false, then calls this.stop(), which works as expected and makes WebRenderer hide the subtitle container by dispatching ClockEvent.Stop.

Then calling this.enable(), sets this._enabled but subsequent this.tick() calls call this.play() which doesn't send the ClockEvent.Play event, because it isn't this._paused is false (the this.pause() call during this.disable() did nothing). Since no ClockEvent.Play is received WebRenderer doesn't restore the visibility of the subtitle container.

What I would expect to work:

webRenderer.disable();
webRenderer.enable();

What's actually needed:

webRenderer.disable();
webRenderer.enable();
manualClock.pause();
manualClock.play();

Support `catch` in `Promise` shim

For compatibility with the official API (and browsers' native implementations). I think this should be a couple extra prototypes in the interface section and a 1-line wrapper function.

Rotation

  • Partial implementation in this branch - diff
  • Rotation is always applied in the order Y-X-Z
  • Rotations apply from the point where they're defined till the end of the line or till they're redefined. However, a redefined rotation is always measured from the zero of the screen. For example, the line M{\fry60}N{\fry60}O will cause O to be rotated a total of 60 degrees, not 120.
  • When individual angles of rotation are thus overridden, the other angles remain unmodified. For example, in the line M{\frz45\fry60}N{\fry0}O, M will be rotated by 0-0-0, N will be rotated by 60-0-45 and O by 0-0-45
  • However, this cannot be rendered as completely separate rotations. In the previous example, the N will be slightly into the screen due to the 60 degrees Y-angle, and the O will be also into the screen (but parallel to the X-Y plane). Effectively the O will be in a plane closer to the viewer than the M, and so will appear larger.

All these facts combined mean that rotations must nest. The line M{\frz45\fry60}N{\fry0}O{\frx90\frz30}P must be rendered as follows:

<span id="1">M<span id="2">N<span id="3">O<span id="4">P</span></span></span></span>

with the following transforms on each:

#1: .transform = "";
#2: .transform = "rotateY(60deg) rotateX(0deg) rotateZ(-45deg)";
#3: .transform = "rotateZ(45deg) rotateX(-0deg) rotateY(-60deg) " + // undo existing rotation to reset back to 0
                 "rotateY(0deg) rotateX(0deg) rotateZ(-45deg)"; // apply new rotation
#4: .transform = "rotateZ(45deg) rotateX(-0deg) rotateY(-0deg) " + // undo existing rotation to reset back to 0
                 "rotateY(0deg) rotateX(90deg) rotateZ(-30deg)"; // apply new rotation

The only thing that should start a top-level span with no reversed rotation applied first is a \N


Unfortunately browsers implement rotation in a retarded manner. All rotations are done from scratch, i.e., if the parent element is rotated, the child element's rotation is not applied on top of the parent's rotation. Instead, it's applied as if the way the child is visible right now is the 0-0-0 state. Thus there is no way to undo a parent's rotation on a child and apply a new rotation.

<style type="text/css">div { display: inline-block; }</style>
<div><div>ABCD</div></div>
<div style="-webkit-transform: rotateY(60deg); transform: rotateY(60deg);"><div>ABCD</div></div>
<div style="-webkit-transform: rotateY(60deg); transform: rotateY(60deg);"><div style="-webkit-transform: rotateY(-60deg); transform: rotateY(-60deg);">ABCD</div></div>

Notice how the third div doesn't look like the first. The child doesn't have the parent's 60deg rotation reversed, instead it has a -60deg rotation applied to its appearance due to the parent rotation (second div).

Another example: http://jsfiddle.net/ag5dQ/4/ Notice how .child_b1 is the same size as .child_b, but .child_b2 isn't.

Support some form of automatic line breaking

  • Not accurate, but text width can be estimated based on font size and number of characters in the span.
  • A more accurate method is using the 2-D context of a canvas but doing that for each sub might be overkill.
  • How to take rotations / dynamic font sizes into account? Dynamic font sizes are especially important for borderline cases like the default style font or first few characters of the line being in a super-huge font while the rest of the line is in tiny font.

Support kfx

  • \k should be trivial to implement with animation-timing-function: step-end Done.
  • \ko is harder - there's no CSS property to animate.
  • \K's sweeping behavior may be impossible to do with just CSS - might require two overlapping spans and an animated width. Also see [https://stackoverflow.com/questions/23569441/is-it-possible-to-apply-css-to-half-of-a-character](this SO question.)

"Outline" style issue in Chrome

Outline looks pretty wrong/ugly after Chrome update. Probably that caused by new way of rendering fonts in Chrome (now chrome uses Direct Write as I understand).

Screenshot (in Chrome):
chrome test
Screenshot (in Firefox):
firefox test
Screenshot (in Aegisub):
aegisub test

Test script:

[Script Info]
Title: Test
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
ScaledBorderAndShadow: yes
YCbCr Matrix: TV.601
Last Style Storage: Default
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Main,Arial,42,&H00FFFFFF,&H000000FF,&H00331B2F,&H00000000,-1,0,0,0,100,100,0,0,1,1.8,0,2,20,20,35,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:10:00.00,Main,,0,0,0,,Lorem ipsum dolor sit amet

SVG outlines are blocky and don't touch the text

The fix for #52 introduced multiplying the SourceAlpha by 1e6 to try to get the equivalent of SourceAlpha but with value 1 at all points instead of the actual source value. This has the downside that the result is blocky and slightly larger than the source, so not only are the outer edges of the outline blocky, but excluding the multipled alpha from the outlines leaves a noticeable clear gap around the source.

font size changed in libjass

hello
i have two problem after using libjass on website
the first is about support fonts
i think the pre-loading not work properly
i have all the font in my pc and also i have attached font to the script
but here photo of what appears

in libass
http://im49.gulfup.com/8NvrgU.png
23_001_2779

in libjass
http://im49.gulfup.com/Bp3V1O.png
23_003_2779

the second problem with font size... sometimes become smaller and sometime bigger

here in libass
http://im49.gulfup.com/8NvrgU.png
23_001_2779

and here in libjass
http://im49.gulfup.com/Yn5u5K.png
23_002_2779

[Script Info]
; Script generated by Aegisub 2.1.8
; http://www.aegisub.org/
Title: العربية
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
YCbCr Matrix: TV.601
Last Style Storage: rapu
Video File: ?dummy:23.976000:40000:1280:720:47:163:254:c
Video Aspect Ratio: 0
Video Zoom: 3
Video Position: 33204

[Aegisub Project Garbage]
Audio File: ../../274 [720p].mkv
Video File: ../../274 [720p].mkv
Video AR Mode: 4
Video AR Value: 1.777778
Video Zoom Percent: 0.250000
Scroll Position: 146
Active Line: 152
Video Position: 830

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Adobe Arabic,63,&H00FFFFFF,&H00FFFFFF,&H00020203,&H00000000,-1,0,0,0,104.274,100,0,0,1,1.7,0.74,2,21,21,30,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:01:55.90,0:01:58.19,Default,,0000,0000,0000,,!عليّ أن أسأل أحد شينوبي السحاب حول طريقة استعمالها

Support .srt

Either:

  • Same way as VSFilter - pretend it's an ASS.
    • Add a type parameter to ASS.fromString to select between ASS and SRT.
    • Implement via default script properties and style.
    • SRT doesn't specify resolution, it uses video resolution.
    • Map SRT formatting to ASS parts.
    • Partial implementation in this branch - diff

or

  • Don't do anything. Browsers support / will support WebVTT natively and it is trivial to convert SRT to WebVTT (prepend "WEBVTT\n\n" and serve as text/vtt).

dist and bower

Any chance that you'll create a bower package or check in the compiled libjass.js and libjass.css?

libjass is more front-end centric and having a compiled version of the essential files will simplify dependency management of other front-end projects using libjass.

Checking in the compiled files for every new tag/release would be great.

Thanks

Font name should not be quoted when it's a CSS keyword

For example, Style defaults fontName to sans-serif if the ASS doesn't specify one. Such a keyword is supposed to be used without quotes for the CSS font-family property, otherwise it's interpreted as a real font name instead of a keyword.

Wrong font color when using opacity

libjass with enableSvg = true:
2015-08-02_19-18-06

libjass with enableSvg = false: (notice that it darken than previous, it more noticeable on colored text)
2015-08-02_19-16-20

Aegisub (libass):
test5_001_12

Script:

[Script Info]
Title:
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 1,0:00:00.00,0:00:36.95,Default,,0,0,0,,{\alpha&7E&}test

Maybe just remove rgba from "color" and "text-shadow" and add "opacity". I tried it via debugger and seems like everything is okay.

For example replace:

color: rgba(255, 255, 255, 0.686275);
text-shadow: rgba(19, 7, 2, 0.686275) 0px 0px 0px, ...many shadows...;

to:

opacity: 0.686275;
color: rgb(255, 255, 255);
text-shadow: rgb(19, 7, 2) 0px 0px 0px, ...many shadows...;

Or is there some kind of pitfall?

Don't always invalidate pre-rendered dialogues on resize / ratechanged

  • Store two more pieces of metadata with each pre-rendered sub - whether it has size-related values, and whether it has time-related values. This includes animations.
  • On resize, only clear those pre-rendered subs (and their associated animations) that have size-related values.
  • On ratechange, only clear those pre-rendered subs (and their associated animations) that have time-related values.

Fix some names

Style.OutlineWidth -> OutlineThickness
{parts, SpanStyles}.OutlineWidthX -> OutlineWidth
{parts, SpanStyles}.OutlineWidthY -> OutlineHeight

Fix fscx-clipping

fscx scaling via transform: scaleX(...) causes the scaled text to clip its neighbors. One alternative is to do the following transformation:

Given:

fontSize = f
fontScaleX = x
fontScaleY = y

Transform to:

fontSize = f * x
fontScaleX = 1
fontScaleY = y / x

and drop the scaleX(...)

The problem is that lines like {\fs12\fscx1000\fscy100} (f = 12, x = 10, y = 1 => f = 120, x = 1, y = 0.1) will end up having a line height of 120px; the 0.1 vertical scaling will not allow the line height to be set to 12px. This does not happen.

Better Example

Hi, i'm relatively new to Javascript, i've seen the ''online demo'', it works fine, but the script is too complex to understand and edit, is it possible a simple ''hello world script''?
Something like:
-script-
var video = VIDEO_URL
var sub = ASS_URL
//SOME CODE TO RUN LIBJASS on idvideo
-/script-
-video id='idvideo'- -/video-

Thanks for attention

Font scale + rotation leads to wrong rotation degree

In libjass:
2015-08-01_21-14-36

In Aegisub (libass):
libass

Test script:

[Script Info]
Title: 
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 1280
PlayResY: 720
Scroll Position: 0
Active Line: 0
Video Zoom Percent: 1
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Trebuchet MS,54,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,2.55,0,2,0,0,42,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.00,0:10:00.00,Default,,0,0,0,,{\fs50\frz22.962\fscx180\pos(812.95,394)}1111111111111111111111111111111111
Dialogue: 0,0:00:00.00,0:10:00.00,Default,,0,0,0,,{\fs50\frz22.962\pos(812.95,394)}2222222222222222222222222222222222222

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.