@kaliber/use-subtitles
Version:
Hook to easily consume your HTMLMediaElement WebVTT subtitles.
173 lines (125 loc) • 5.57 kB
Markdown
# `/use-subtitles`
Easily consume your video elements' WebVTT subtitles in React.
## Motivation
WebVTT subtitles are a great feature, but they come with some difficulties:
- Styling the subtitles with CSS to achieve a consistent look across browsers can be challenging.
- Third party dependencies hide the underlaying `HTMLMediaElement`, and thus;
- Interfacing with the subtitles from JavaScript code is not straightforward.
**This hook aims to make that easier for you.**
## Installation
```
yarn add /use-subtitles
```
#### Transpilation
When working with `/build`, add `@kaliber/use-subtitles` to your `compileWithBabel` array.
## Usage
Here's a short example demonstrating the most common use case.
```jsx
import { useSubtitles } from '@kaliber/use-subtitles'
function Component() {
const { ref } = useSubtitles({
language: "en"
})
return (
<video {... { ref }}>
<source type="audio/mp3" src="./audio.mp3" />
<track src="./subtitle.vtt" kind="subtitles" srcLang="en" default />
</video>
)
}
```
Look at the [`/example`](/example) directory for further examples.
## Usage with `ReactPlayer`
As long as you are able provide the underlying `HTMLMediaElement` of your dependency, the library should work.
Because `ReactPlayer` only provides the underlaying ref whenever it deems it ready, we need to set it through the `onReady` method (up until that time, its value will otherwise be `null`).
```jsx
import { useSubtitles } from '@kaliber/use-subtitles'
import ReactPlayer from 'react-player'
const config = {
file: { tracks: [{
kind: "subtitles",
src: "/subtitle.vtt",
srcLang: "en",
default: true
}]}
}
function Component() {
const reactPlayerRef = React.useRef(null)
const { current, ref } = useSubtitles({
language: "en"
})
return (
<ReactPlayer
ref={reactPlayerRef}
onReady={x => { ref.current = x.getInternalPlayer() }}
url="./audio.mp3"
{... { config }}
/>
)
}
```
## Parameters
The hook accepts the following parameters:
| Key | Type | Example | Description |
| ------------- | ------------- | ------------- | --- |
| `language` | `string` | `nl` | Expects a language code that matches the `track` language. Bear in mind this has to be a [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) string. For example in case of Japan, `jp` does not work in all browsers, where `ja` does, which is the valid ISO code. |
## Return values
The `useSubtitles` hook returns the following values:
| Key | Initial values | Description |
|-----------------| --- |---------------------------------------------------------------------------------------------------------------|
| `subtitles` | `[]` | An array of all subtitles available for the specified language. |
| `metadata` | `[]` | An array of all metadata available for the specified language. |
| `active` | See below. | An object representing the currently active subtitle and metadata, with metadata containing the properties `startTime`, `endTime`, and `text`, and subtitle also containing `voice`[^1]. |
| `ref` | `{ current: null }` | A reference that should be attached to the player element ref attribute. |
#### The structure of the `active` object:
```js
{
subtitles: {
[key]: null
},
metadata: {
[key]: null
}
}
```
[^1]: `voice` represents the current speakers' name.
## WebVTT
A WebVTT file typically looks like this:
```vtt
WEBVTT
00:00:00.000 --> 00:00:20.000
<v Fred>Hi, my name is Fred
00:00:02.500 --> 00:00:22.500
<v Bill>Hi, I’m Bill
00:00:05.000 --> 00:00:25.000
<v Fred>Would you like to get a coffee?
00:00:07.500 --> 00:00:27.500
<v Bill>Sure! I’ve only had one today.
00:00:10.000 --> 00:00:30.000
<v Fred>This is my fourth!
00:00:12.500 --> 00:00:32.500
<v Fred>OK, let’s go.
```
## Metadata
This hook also has the option to extract metadata; additional data to support the subtitles, but are not directly shown to the user. This accepts JSON (which it parses and returns), or a regular string.
Example of a WebVTT metadata file (with `JSON`):
```vtt
WEBVTT
00:00:00.000 --> 00:00:01.000
{ "text": "Living on borrowed time", "color": "red" }
00:00:01.000 --> 00:00:02.400
{ "text": "the clock ticks faster.", "color": "red" }
```
Look at the `Karaoke` example for an implementation.
#### Extracted properties
`use-subtitles` extracts some of the available data from the cues. Here's an overview of _what_ it extracts, and how that is returned.
| Kind | Description |
| ---- | ----------- |
| `00:00:00.000 --> 00:00:20.000` | Timestamp. Outputted under `current.startTime` and `currrent.endTime`, and available for all cues in the `subtitles` array. |
| `<v Fred>` | `voice`-tag. Outputted by hook under `current.voice`. |
| `Hi, my name is Fred` | The `text`, available under `current.text`, and available for all cues in the `subtitles` array as `text`. |
---

## Disclaimer
This library is intended for internal use, we provide __no__ support, use at your own risk. It does not import React, but expects it to be provided, which [/build](https://kaliberjs.github.io/build/) can handle for you.
This library is not transpiled.