-
Notifications
You must be signed in to change notification settings - Fork 2
Architecture Overview
Let's talk about sub37
architecture. Here we'll provide an overview, as it will get more and more detailed as you keep reading across the pages.
When building a subtitle system, there are initially 2 components to take into consideration. Two components that answer the following questions:
- What will handle the timed painting of the subtitles on the screen?
- What will handle the timed serving of the subtitles so that they can be rendered?
There are some common terms used to describe them: respectively a renderer
and a server
. Of course, "server" must not be intended as the "server" of the Client-Server Architecture: we are at a higher knowledge level here and we are working on the client side.
Then, deep diving into the world of subtitles, another question pops up: what will handle them? The answer might be still "server", but there's a thing to take into consideration: subtitles are data that can be interpreted in several ways and in several layers of interpretation.
For example, WebVTT is a binary data stream that has already been read by a computer and is understood as a string. But still, it can be understood again as a set of specific information: some metadata information (regions, styles, timings, ...) and some contents that will be shown to humans once parsed.
Another example could be the TTML format. It is a binary data stream that has already been read by a computer and is understood as a string. But still, it can be read in a specific format, which is XML. XML consists of tags, attributes, contents... I think you got the point.
So, as long as the format to understand is only one, we could put the logic that parses everything in the server
component. But once that the formats to be supported become more than one, it can easily become difficult to handle everything in just one library. You end up with high maintenance costs and a lot of code to be handled.
Here comes the architectural solution: an adapter and a common format.
Architecturally speaking, for those of you that do not know, an adapter is a way to transform some data into a known format to allow components to be independent. The known format is defined as where the main logic is built (in our case the "server"). It is not said that in the architecture there will be only one adapter: many can exist and data can be transformed several times before achieving the last one.
In Dragonball's Italian translation, it is called "Freezer" instead of "Frieza"
So here we get to the current architecture:
- A renderer (
@sub37/captions-renderer
) that will handle whatever is about creating elements and showing subtitles to users; - The server (
@sub37/server
) that will serve in a timed manner the subtitles to be shown; - Some adapters (like
@sub37/webvtt-adapter
), will know how to parse the content and return the structure in the format known by the server.
Such architecture obliviously offers the possibility to replace both the adapters and the renderer, even if the renderer is there to stay (in fact, creating a new renderer might not be worth the time).
So, here below a diagram of how the whole system works:
One of the main goals for this library was to achieve human-friendly error handling. When a library is modular and swappable with modules out of your control (someone might be interested in creating its own adapter for its own proprietary subtitles data format), you cannot let things get easily out of control.
There could be several points of failure in a library like this. That's why it is important to estimate which could be the possible failures, how to catch them, and how to make them human-friendly.
All the errors in this library extend the native Error
class and have some extensive error messages that explain what is happening, either the issue is nested or not.