I have a video file on my local disk. I also have some subtitles (in HTML5's WebVTT format).
I want to create an HTML file to play that video with subtitles, all from the local filesystem.
Loading an external VTT file from the local filesystem fails due to same-origin policy.
Disable cross-origin protection in the browser.
While it works, it is troublesome and dangerous. Please don't do it.
Try embedding the VTT file as a data:
URI inside <track src="">
.
Unfortunately, I still got issues related to cross-origin, so I abandoned this idea.
I had trouble in 2016, but now in 2024 this solution works fine! According to the comments, it has been working fine since 2022 or earlier. However, this solution has a few drawbacks:
data:
URIs are ugly. The nice human-readable subtitle files have to be converted to an ugly string of characters.data:
URIs might have size limits, which means longer subtitles may not work correctly.- Due to encoding,
data:
URIs are larger than raw VTT files.
It still has a few advantages, though:
- No JavaScript required, just plain HTML.
- Works fine enough for shorter subtitles.
Try embedding the VTT file inside the HTML file, generating a Blob URL, and adding a new <track src="">
to the video.
Unfortunately, it did not work for me.
I had trouble in 2016, but now in 2024 this solution works fine! Probably because the VTT format doesn't allow any leading whitespace, so we need to use .trimStart()
when extracting the text from the <script>
tag. Thanks to @hugoheden for figuring it out!
Try embedding the SRT file inside the HTML file and use JavaScript code to dynamically parse and display the subtitles.
That was my previous attempt, I used a highly modified version of VideoSub. Still, this solution felt a bit bloated, specially because it runs JavaScript code while the video is playing. In addition, it was insecure, because it added the subtitle text directly through innerHTML
.
Try embedding the VTT file inside the HTML file and dynamically create a new Text Track when the document loads.
This is the solution implemented in this Gist. It is relatively small (the bigger portion is the VTT parser), and the JavaScript code runs only once (when the document is loading).
The text style can be tweaked using video::cue
selector. Styling can be refined, for instance, we can set the style of underlined subtitles through video::cue(u)
selector.
These examples in this Gist are assuming you have only one subtitle track and you want it to be enabled by default. Adding support for multiple tracks is left as an exercise to the reader. (Or just look at the comments down below, someone might have implemented it.)
@bkimminich, it's fine, feel free to reuse my solution any way you like. Credits are always appreciated, but of course not required. (Also, GitHub doesn't always send notifications for comments on Gists.)