Installation
pnpm add ass-html5v0.6.0
Minor Changes
- e8c46a1: Implementig most of the SSA features
Full Changelog: https://github.com/luxluth/ass-html5/compare/v0.5.4…v0.6.0
Features
- Karaoke Support: Full support for
\k,\kf,\ko, and\Ktags. - Vector Drawings: High-performance rendering of ASS vector paths (
\p) usingPath2D. - Clipping: Support for rectangular and vector clipping/masking (
\clip,\iclip). - Advanced Transformations:
- Rotation around all axes (
\frz,\frx,\fry). - Scaling (
\fscx,\fscy) and Shearing (\fax,\fay). - Custom rotation origin (
\org).
- Rotation around all axes (
- Smart Wrapping: Implementation of
\qstyles for optimal line breaking. - Collision Handling: Automatic vertical shifting to prevent overlapping subtitles.
- Blur Effects: Edge blur (
\be) and Gaussian blur (\blur) using Canvas filters. - Performance Optimized: Built-in layer caching to minimize redundant redraws.
Examples
Native Player
Basic native player example. In fullscreen mode, the subtitles will not be visible.
code
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/ass-html5@0.6.0/dist/ass.min.js" defer></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Native player</title>
</head>
<body>
<video id="video" controls preload="auto">
<source src="https://v.animethemes.moe/Kaijuu8Gou-ED1.webm" type="video/webm" />
</video>
</body>
<script>
var fonts = [
{
family: 'Trebuchet MS',
url: '/fonts/trebuc_0.ttf',
descriptors: { style: 'normal' }
}
];
document.addEventListener('DOMContentLoaded', async () => {
let res = await fetch('/examples/kaiju.ass');
let assSubs = await res.text();
const ass = new ASS.default({
assText: assSubs,
video: document.getElementById('video'),
fonts: fonts
});
await ass.render();
});
</script>
</html>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
background-color: #17181c;
height: 100%;
width: 100%;
}
body {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
video {
width: 100%;
height: 100%;
}
</style>
subtitles
[Script Info]
; Script generated by Aegisub 3.3.3
; http://www.aegisub.org/
ScriptType: v4.00+
PlayResX: 3840
PlayResY: 2160
ScaledBorderAndShadow: yes
YCbCr Matrix: TV.709
[Aegisub Project Garbage]
[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,120,&H0000BAFF,&H00000000,&H00000000,&H00000000,-1,-1,0,0,133,100,0,0,1,3,3.6,8,100,100,75,1
Style: Bright,Trebuchet MS,120,&H00FFFFFF,&H00000000,&H0000BAFF,&H00000000,-1,-1,0,0,133,100,0,0,1,3,3.6,8,100,100,75,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.63,0:00:03.57,Default,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:04.00,0:00:07.05,Default,,0,0,0,,Whatever demons u fighting through
Dialogue: 0,0:00:07.45,0:00:10.52,Default,,0,0,0,,When you need somebody to turn to
Dialogue: 0,0:00:10.94,0:00:13.86,Default,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:14.89,0:00:17.46,Bright,,0,0,0,,I’d take the fall
Dialogue: 0,0:00:17.76,0:00:20.91,Bright,,0,0,0,,If ever you feel like there’s no one at all
Dialogue: 0,0:00:21.20,0:00:21.70,Bright,,0,0,0,,Ah yea and
Dialogue: 0,0:00:21.70,0:00:24.35,Bright,,0,0,0,,I’d stay through the night
Dialogue: 0,0:00:24.65,0:00:27.74,Bright,,0,0,0,,When you got monsters tryna take you alive
Dialogue: 0,0:00:28.09,0:00:31.17,Bright,,0,0,0,,There ain’t no people or lines
Dialogue: 0,0:00:31.65,0:00:34.59,Bright,,0,0,0,,That i wouldn’t cross if u need me to
Dialogue: 0,0:00:34.89,0:00:38.27,Bright,,0,0,0,,I’m out here steppin on mines
Dialogue: 0,0:00:38.59,0:00:41.50,Bright,,0,0,0,,And I think it’s finally time that you knew
Dialogue: 0,0:00:41.79,0:00:45.10,Bright,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:45.21,0:00:48.26,Default,,0,0,0,,Whatever demons u fightin through
Dialogue: 0,0:00:48.61,0:00:51.59,Default,,0,0,0,,When you need somebody to turn to
Dialogue: 0,0:00:52.06,0:00:54.06,Default,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:55.27,0:00:58.61,Bright,,0,0,0,,Nobody got u without no shade
Dialogue: 0,0:00:58.89,0:01:02.04,Bright,,0,0,0,,I’ll take the good and the bad all day
Dialogue: 0,0:01:02.20,0:01:05.45,Bright,,0,0,0,,When you need somebody to turn to
Dialogue: 0,0:01:05.56,0:01:08.95,Bright,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:01:09.62,0:01:12.11,Bright,,0,0,0,,Nobody Nobody Nobody
Dialogue: 0,0:01:13.03,0:01:15.67,Bright,,0,0,0,,Got you the way I do
Dialogue: 0,0:01:16.89,0:01:18.89,Bright,,0,0,0,,Nobody Nobody Nobody
Dialogue: 0,0:01:19.47,0:01:22.12,Bright,,0,0,0,,Nobody got you the way I do
video
VideoJs
An example that uses the well known videojs
code
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://cdn.jsdelivr.net/npm/ass-html5@0.6.0/dist/ass.min.js" defer></script>
<script src="https://vjs.zencdn.net/8.3.0/video.min.js" defer></script>
<link href="https://vjs.zencdn.net/8.3.0/video-js.css" rel="stylesheet" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Videojs player player</title>
</head>
<body>
<video id="video" class="video-js" controls preload="auto" data-setup="{}">
<source src="https://v.animethemes.moe/Kaijuu8Gou-ED1.webm" type="video/webm" />
</video>
</body>
<script>
var fonts = [
{
family: 'Trebuchet MS',
url: '/fonts/trebuc_0.ttf',
descriptors: { style: 'normal' }
}
];
document.addEventListener('DOMContentLoaded', async () => {
let res = await fetch('/examples/kaiju.ass');
let assSubs = await res.text();
var player = videojs('video');
player.ready(async () => {
// Get the video element from the player
var videoElement = player.el().getElementsByTagName('video')[0];
const ass = new ASS.default({
assText: assSubs,
video: videoElement,
fonts: fonts
});
await ass.render();
});
});
</script>
</html>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
background-color: #17181c;
height: 100%;
width: 100%;
}
body {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#video {
width: 100%;
height: 100%;
}
</style>
subtitles
[Script Info]
; Script generated by Aegisub 3.3.3
; http://www.aegisub.org/
ScriptType: v4.00+
PlayResX: 3840
PlayResY: 2160
ScaledBorderAndShadow: yes
YCbCr Matrix: TV.709
[Aegisub Project Garbage]
[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,120,&H0000BAFF,&H00000000,&H00000000,&H00000000,-1,-1,0,0,133,100,0,0,1,3,3.6,8,100,100,75,1
Style: Bright,Trebuchet MS,120,&H00FFFFFF,&H00000000,&H0000BAFF,&H00000000,-1,-1,0,0,133,100,0,0,1,3,3.6,8,100,100,75,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.63,0:00:03.57,Default,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:04.00,0:00:07.05,Default,,0,0,0,,Whatever demons u fighting through
Dialogue: 0,0:00:07.45,0:00:10.52,Default,,0,0,0,,When you need somebody to turn to
Dialogue: 0,0:00:10.94,0:00:13.86,Default,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:14.89,0:00:17.46,Bright,,0,0,0,,I’d take the fall
Dialogue: 0,0:00:17.76,0:00:20.91,Bright,,0,0,0,,If ever you feel like there’s no one at all
Dialogue: 0,0:00:21.20,0:00:21.70,Bright,,0,0,0,,Ah yea and
Dialogue: 0,0:00:21.70,0:00:24.35,Bright,,0,0,0,,I’d stay through the night
Dialogue: 0,0:00:24.65,0:00:27.74,Bright,,0,0,0,,When you got monsters tryna take you alive
Dialogue: 0,0:00:28.09,0:00:31.17,Bright,,0,0,0,,There ain’t no people or lines
Dialogue: 0,0:00:31.65,0:00:34.59,Bright,,0,0,0,,That i wouldn’t cross if u need me to
Dialogue: 0,0:00:34.89,0:00:38.27,Bright,,0,0,0,,I’m out here steppin on mines
Dialogue: 0,0:00:38.59,0:00:41.50,Bright,,0,0,0,,And I think it’s finally time that you knew
Dialogue: 0,0:00:41.79,0:00:45.10,Bright,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:45.21,0:00:48.26,Default,,0,0,0,,Whatever demons u fightin through
Dialogue: 0,0:00:48.61,0:00:51.59,Default,,0,0,0,,When you need somebody to turn to
Dialogue: 0,0:00:52.06,0:00:54.06,Default,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:00:55.27,0:00:58.61,Bright,,0,0,0,,Nobody got u without no shade
Dialogue: 0,0:00:58.89,0:01:02.04,Bright,,0,0,0,,I’ll take the good and the bad all day
Dialogue: 0,0:01:02.20,0:01:05.45,Bright,,0,0,0,,When you need somebody to turn to
Dialogue: 0,0:01:05.56,0:01:08.95,Bright,,0,0,0,,Nobody got you the way I do
Dialogue: 0,0:01:09.62,0:01:12.11,Bright,,0,0,0,,Nobody Nobody Nobody
Dialogue: 0,0:01:13.03,0:01:15.67,Bright,,0,0,0,,Got you the way I do
Dialogue: 0,0:01:16.89,0:01:18.89,Bright,,0,0,0,,Nobody Nobody Nobody
Dialogue: 0,0:01:19.47,0:01:22.12,Bright,,0,0,0,,Nobody got you the way I do