Display ASS/SSA subtitles on html video

Installation

pnpm add ass-html5

v0.5.3

Patch Changes

  • b1053bf: [fix] single character color alternating not displayed

What's Changed

  • fix: single character color alternating not displayed by @Dastan21 in https://github.com/luxluth/ass-html5/pull/103
  • Version Packages by @github-actions in https://github.com/luxluth/ass-html5/pull/105

New Contributors

  • @Dastan21 made their first contribution in https://github.com/luxluth/ass-html5/pull/103

Full Changelog: https://github.com/luxluth/ass-html5/compare/v0.5.2…v0.5.3

This Project is still under development. There is a loads of missing features.

With the simple video tag element, on fullscreen mode, the position of the video is absoluty on top of any element. No other element can go on top of it.

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.5.3/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.5.3/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
video