An open API service indexing awesome lists of open source software.

https://github.com/luxluth/ass-html5

Display ASS/SSA subtitles for html video
https://github.com/luxluth/ass-html5

aegisub ass-subtitles html-canvas html5 javascript libass ssa-subtitles subtitles typescript

Last synced: 2 months ago
JSON representation

Display ASS/SSA subtitles for html video

Awesome Lists containing this project

README

          

# ass-html5

Display ASS/SSA subtitles on html5 videos

![CI workflow](https://github.com/luxluth/ass-html5/actions/workflows/main.yml/badge.svg)
![Publish workflow](https://github.com/luxluth/ass-html5/actions/workflows/publish.yml/badge.svg)
![License](https://img.shields.io/github/license/luxluth/ass-html5?color=blue)
![npm bundle size](https://img.shields.io/bundlephobia/min/ass-html5)
![npm](https://img.shields.io/npm/v/ass-html5?logo=npm&color=white&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fass-html5)

## Table of Contents

- [ass-html5](#ass-html5)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Features](#features)
- [Usage](#usage)
- [Options](#options)
- [Simple HTML](#simple-html)
- [Svelte and Plry](#svelte-and-plry)
- [videojs](#videojs)
- [Credits](#credits)

## Installation

```bash
pnpm add ass-html5
```

## Features

- **Karaoke Support**: Full support for `\k`, `\kf`, `\ko`, and `\K` tags.
- **Vector Drawings**: High-performance rendering of ASS vector paths (`\p`) using `Path2D`.
- **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`).
- **Smart Wrapping**: Implementation of `\q` styles 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.

## Usage

### Options

| option | description | required | type | default |
| :-----: | :---------------------------------------------------------------------------------------------------------: | :------: | :---------------------------: | :-------------------: |
| assText | The ass text string | 🚫 | `string` | `undefined` |
| subUrl | URL to fetch the ASS content from | 🚫 | `string` | `undefined` |
| video | The video to display the subtile on. Can be either an `HTMLVideoElement` or `string` (html query selector ) | ✅ | `HTMLVideoElement` / `string` | `undefined` |
| fonts | Custom fonts to load | 🚫 | [`Font[]`](src/ass.ts#L78) | `undefined` |
| zIndex | zIndex of the rendering frame | 🚫 | `number` | Drawn after the video |
| onReady | A Callback that is invoked when the preprocess of the ass text by render is done | 🚫 | `() => void` | `undefined` |
| logging | Type of logging | 🚫 | [`LOGTYPE`](src/ass.ts#L50) | `LOGTYPE.DISABLE` |

> One of `assText` or `subUrl` is required.

### Simple HTML

> [!NOTE]
> The simple `video` tag element, in fullscreen mode, the position of the video is absolutely on top of any element.
> No other element can go on top of it.
>
> It's therefore recommended to use a third party player rather than the native one. You can see an example with [plry](https://github.com/sampotts/plyr) [here](#svelte-and-plry).

```html

```

```html

```

```html

document.addEventListener('DOMContentLoaded', async () => {
// Using subUrl to fetch subtitle automatically
const ass = new ASS.default({
subUrl: '/assets/video.ass',
video: document.getElementById('video')
});
await ass.render();

// You can switch subtitles dynamically:
// await ass.setSubUrl('/assets/other.ass');
// OR
// await ass.setAssText('[Script Info]...');
});

```

### [Svelte](https://github.com/sveltejs/svelte) and [Plry](https://github.com/sampotts/plyr)

```svelte

import video from '$lib/assets/video.mp4'
import cc from '$lib/assets/cc.ass?url'
import ASS from 'ass-html5'
import { onMount } from 'svelte';
import Plyr from 'plyr'

const ass = new ASS({
subUrl: cc,
video: "#video-test"
})

let vidElement: HTMLVideoElement
let player: Plyr
onMount(async () => {
player = new Plyr(vidElement)
await ass.render()
})





```

### [videojs](https://github.com/videojs/video.js)

In the `head` :

```html

```

In the `body` :

```html

```

In the `script` tag :

```html

document.addEventListener('DOMContentLoaded', async () => {
let res = await fetch('/assets/video.ass');
let assSubs = await res.text();

var player = videojs('my-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
});
await ass.render();
});
});

```

---

# Credits

Thanks to the [ass-compiler](https://github.com/weizhenye/ass-compiler/) by weizhenye.