Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebVTT Caption Alignment #5775

Closed
streamingsystems opened this issue Aug 29, 2023 · 4 comments
Closed

WebVTT Caption Alignment #5775

streamingsystems opened this issue Aug 29, 2023 · 4 comments

Comments

@streamingsystems
Copy link

What do you want to do with Hls.js?

Hi All,

I searched google and also did some searching on GitHub without any luck. If there is already an answer please share :)

I am creating my own master and variant playlists including WebVTT captioning. I am having a little trouble shifting/delaying the captions to line up exactly where I need them to be.

I have a DISCONTINUITY in my variant playlist which causes the PTS in the TS file to reset to 0 (or close to 0) right before the captions start.

Per the Apple specification it seems like I can use:

X-TIMESTAMP-MAP

To map between the PTS in the TS chunks and the cue times in the subtitles.

However, I read a posting that hls.js does not seem to use PTS from the TS. In that same post it seems to imply that hls.js uses EXT-X-PROGRAM-DATE-TIME, but I could not understand if that was definitive.

Could you please explain to me the process that hls.js uses to figure out the timing/matching of the cue times (eg. 00:00:02.060 --> 00:00:05.600) to the TS files that are coming down (that contain PTS time stamps).

(I tried to read over the source but I am not very proficient at JavaScript like I am other languages).

Thanks!

What have you tried so far?

I did some searches on GitHub and Google.

@streamingsystems streamingsystems added Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. Question labels Aug 29, 2023
@robwalch
Copy link
Collaborator

robwalch commented Aug 31, 2023

hls.js uses PTS when mapping with WebVTT headers X-TIMESTAMP-MAP (it has to). Just make sure you have the same discontinuities in your subtitle playlists that you have in your video/audio playlists. If you have a DISCONTINUITY at 60 seconds in your media playlists, you need to have one in subtitles as well so that all subtitle segments can be aligned with audio and video appropriately.

@robwalch robwalch removed the Needs Triage If there is a suspected stream issue, apply this label to triage if it is something we should fix. label Aug 31, 2023
@streamingsystems
Copy link
Author

streamingsystems commented Aug 31, 2023 via email

@robwalch
Copy link
Collaborator

robwalch commented Aug 31, 2023

initPTS, for each discontinuity sequence, maps the difference between the HTMLMediaElement timeline and the PTS or presentation timestamps. If the first segment has a PTS of 0, then the first initPTS will be 0. An initPTS is established for each discontinuity sequence, referred to as cc index.

Playlist alignment may be performed based on PTD (see alignMediaPlaylistByPDT), but not the actual subtitle cue timing which is handled in parseWebVTT. Playlist alignment does not depend on PTD, since it is not required by HLS, but providing inconsistent date value across playlists and across discontinuity sequence could certainly impact Playlist alignment.

Playlist alignment ultimately impacts which segments are loaded (not subtitle plotting). Just as DISCONTINUITY sequences should be aligned across all playlists so should PROGRAM-DATE-TIME. Having different PDTs or discontinuities across playlists can create ambiguity that clients cannot resolve.

The actual plotting of subtitle cues loaded from subtitle segments is handle in the parsing of the VTT . This is where the media PTS offset (initPTS) and the X-TIMESTAMP-MAP MPEGTS and LOCAL values are used to plot subtitle start and end times:

parser.oncue = function (cue: VTTCue) {
// Adjust cue timing; clamp cues to start no earlier than - and drop cues that don't end after - 0 on timeline.
const currCC = vttCCs[cc];
let cueOffset = vttCCs.ccOffset;
// Calculate subtitle PTS offset
const webVttMpegTsMapOffset = (timestampMapMPEGTS - init90kHz) / 90000;
// Update offsets for new discontinuities
if (currCC?.new) {
if (timestampMapLOCAL !== undefined) {
// When local time is provided, offset = discontinuity start time - local time
cueOffset = vttCCs.ccOffset = currCC.start;
} else {
calculateOffset(vttCCs, cc, webVttMpegTsMapOffset);
}
}
if (webVttMpegTsMapOffset) {
if (!initPTS) {
parsingError = new Error('Missing initPTS for VTT MPEGTS');
return;
}
// If we have MPEGTS, offset = presentation time + discontinuity offset
cueOffset = webVttMpegTsMapOffset - vttCCs.presentationOffset;
}
const duration = cue.endTime - cue.startTime;
const startTime =
normalizePts(
(cue.startTime + cueOffset - timestampMapLOCAL) * 90000,
timeOffset * 90000,
) / 90000;
cue.startTime = Math.max(startTime, 0);
cue.endTime = Math.max(startTime + duration, 0);

@robwalch
Copy link
Collaborator

I am creating my own master and variant playlists

Have you tried validating your work with the HLS Tools mediastreamvalidator?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants