Overview
Use this workflow to convert an external subtitle file to WebVTT in HLS. The reader attaches the file and passes its subtitle packets to the writer. Configure format='hls' and the WebVTT codec:
subtitle::codec='webvtt'The MPlatform example below writes an HLS playlist and .vtt files. For bitmap DVB subtitles or DVB Teletext in MPEG-TS, see ASS/SRT insertion or live insertion.
Workflow
The WebVTT subtitle insertion workflow consists of the following steps:
- Prepare an input media file and an external subtitle file.
- Open the source with
MFile.FileNameSet. - Attach the subtitle file with
external_subtitle. - Enable subtitle packet output from the reader with
experimental.out_subtitle_packets=2. - Configure
MWriterfor HLS output. - Set
subtitle::codec='webvtt'in the writer configuration. - Start the writer and process the source.
- Check the generated
.vttfiles in the HLS output folder.
Reader configuration
The reader must be configured to output subtitle packets from the attached subtitle file. The subtitle file is attached with external_subtitle.
string readerConfig =
"external_process=false " +
"subtitle_track=0 " +
"experimental.out_subtitle_packets=2 " +
@"external_subtitle=C:\Subtitles\example.ass";The options are:
-
external_process=false— disables external processing for this reader path. -
subtitle_track=0— selects the subtitle track. -
experimental.out_subtitle_packets=2— enables subtitle packet output from the reader so the writer can receive and encode the subtitle stream. -
external_subtitle=...— attaches an external subtitle file to the source.
In this example, the external subtitle file is an ASS file:
example.assThe writer converts the subtitle packets from this source into WebVTT subtitle output for HLS.
Writer configuration
To generate HLS with WebVTT subtitles, configure MWriter with format='hls' and subtitle::codec='webvtt'.
format='hls'
mux_buffers=0
hls_time=2
hls_list_size=0
hls_playlist_type='vod'
subtitle::codec='webvtt'
subtitle::metadata::language='eng'
video::codec='libopenh264'
video::maxrate='5M'
audio::codec='aac'
program::title='FIRST TITLE'The main options are:
-
format='hls'— enables HLS output. -
hls_time=2— sets the HLS segment duration. -
hls_list_size=0— keeps all playlist entries. -
hls_playlist_type='vod'— creates a VOD-style HLS playlist. -
subtitle::codec='webvtt'— writes the subtitle stream as WebVTT. -
subtitle::metadata::language='eng'— sets the subtitle language metadata. -
video::codec='libopenh264'— encodes video with OpenH264. -
audio::codec='aac'— encodes audio as AAC.
MPlatform example
The following example opens a source file, attaches an external ASS subtitle file, writes HLS output with WebVTT subtitles, and then checks the generated .vtt files.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using MPLATFORMLib;
public static class WebVttHlsExample
{
public static void WriteWebVttSubtitlesToHls()
{
string writerDestination = Path.Combine(
Path.GetTempPath(),
"HLS_WebVTT");
string outputPlaylist = Path.Combine(writerDestination, "output.m3u8");
string sourcePath =
@"C:\Media\input.ts";
string subtitlePath =
@"C:\Subtitles\example.ass";
string readerConfig =
"external_process=false " +
"subtitle_track=0 " +
"experimental.out_subtitle_packets=2 " +
$"external_subtitle={subtitlePath}";
string writerConfig =
"format='hls' " +
"mux_buffers=0 " +
"hls_time=2 " +
"hls_list_size=0 " +
"hls_playlist_type='vod' " +
"subtitle::codec='webvtt' " +
"subtitle::metadata::language='eng' " +
"video::codec='libopenh264' " +
"video::maxrate='5M' " +
"audio::codec='aac' " +
"program::title='FIRST TITLE'";
MFileClass file = null;
MWriterClass writer = null;
try
{
if (Directory.Exists(writerDestination))
Directory.Delete(writerDestination, true);
Directory.CreateDirectory(writerDestination);
file = new MFileClass();
writer = new MWriterClass();
file.FileNameSet(sourcePath, readerConfig);
file.FilePlayStart();
file.ObjectStateGet(out eMState fileState);
if (fileState != eMState.eMS_Running)
throw new InvalidOperationException("Source file did not start.");
writer.WriterNameSet(outputPlaylist, writerConfig);
writer.ObjectStart(file);
writer.ObjectStateGet(out eMState writerState);
if (writerState != eMState.eMS_Running)
throw new InvalidOperationException("MWriter did not start.");
// Let the writer process the source and generate HLS output.
Thread.Sleep(15000);
writer.ObjectClose();
file.ObjectClose();
string[] vttFiles = Directory.GetFiles(writerDestination, "*.vtt");
StringBuilder vttContent = new StringBuilder();
foreach (string currentFile in vttFiles)
{
string currentContent = File.ReadAllText(
currentFile,
Encoding.UTF8);
vttContent.AppendLine(currentContent);
}
Console.WriteLine(vttContent.ToString());
}
finally
{
if (writer != null)
Marshal.ReleaseComObject(writer);
if (file != null)
Marshal.ReleaseComObject(file);
}
}
}Verify the generated WebVTT subtitles
After writing is complete, the HLS output folder should contain the generated playlist and WebVTT subtitle files.
The generated playlist is written to:
output.m3u8The generated WebVTT subtitle files use the .vtt extension. Applications can check them by reading all .vtt files from the output folder:
string[] vttFiles = Directory.GetFiles(writerDestination, "*.vtt");
StringBuilder vttContent = new StringBuilder();
foreach (string currentFile in vttFiles)
{
string currentContent = File.ReadAllText(currentFile, Encoding.UTF8);
vttContent.AppendLine(currentContent);
}
string result = vttContent.ToString();
Console.WriteLine(result);If the subtitle text from the input subtitle file is present in the generated WebVTT files, the subtitle insertion workflow is working correctly.
For a playback check, open the generated HLS output in a player that supports WebVTT subtitles, select the subtitle rendition, and confirm that a known cue appears at the expected time.
Configuration checklist
- Use a subtitle file with at least one cue in the portion of the source you will process.
- Use
experimental.out_subtitle_packets=2so the reader forwards subtitle packets to the writer. - Keep the generated playlists and subtitle segments together so the player can resolve their relative URLs.
Summary
To write WebVTT subtitles into HLS output, attach the input subtitle file to the reader with external_subtitle, enable subtitle packet output with experimental.out_subtitle_packets=2, and configure the writer with format='hls' and subtitle::codec='webvtt'.
Example subtitle files
The example.ass and example.srt files shipped with the Subtitle Conversion Sample are useful input fixtures. Follow the writer configuration on this page to create HLS output. The DVB controls in the sample demonstrate the separate MPEG-TS workflow.
See also
Still have questions?
Tell us what didn’t work or what you’d like clarified.