question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Show/Hide Subtitle/CC Text Track Events

See original GitHub issue

Q: What should events to show/hide subtitle/cc text tracks look like?

Assumptions:

  • Media Chrome Elements will receive attributes in the form proposed in #59
  • Elements will very likely need to parse these back into JS objects resembling a (partial) TextTrack
  • It’s common to have a single control element for showing/hiding both Subtitles & CC
  • While uncommon, there are cases where users/players would want multiple Subtitles/CCs showing simultaneously.
  • It’s common to have a UI that “disables”/hides any and all currently showing Subtitles & CC

Proposal

Create 2 generic events: one for showing and one for hiding 1+ subtitles/cc text tracks (or both)

Show Text Tracks

  • type: "mediashowtexttracksrequest"
  • detail (required): [{ kind: TEXT_TRACK_KIND, label?: OPTIONAL_TRACK_LABEL, language: TRACK_LANGUAGE }, ...] || { kind: TEXT_TRACK_KIND, label?: OPTIONAL_TRACK_LABEL, language: TRACK_LANGUAGE }

Result: changes any matching TextTrack to mode="showing" (NOTE: In this proposal, this would not change the mode of any currently "showing" TextTrack)

Examples:

// Example 1
const track = { kind: "captions", language: "en_US", label: "English (US)" };
const evt1 = new CustomEvent("mediashowtexttracksrequest", { composed: true, bubbles: true, detail: track });
this.dispatchEvent(evt1);

// Example 2 (multi-select)
const track1 = { kind: "captions", language: "en_US" }; // Assumes this caption track has no `label`
const track2 = { kind: "subtitles", label: "English (with descriptions)", language: "en_US" };
const evt2 = new CustomEvent("mediashowtexttracksrequest", { composed: true, bubbles: true, detail: [track1, track2] });
this.dispatchEvent(evt2);

Hide Text Tracks

  • type: "mediahidetexttracksrequest"
  • detail (optional): [{ kind: TEXT_TRACK_KIND, label?: OPTIONAL_TRACK_LABEL, language: TRACK_LANGUAGE }, ...] || { kind: TEXT_TRACK_KIND, label?: OPTIONAL_TRACK_LABEL, language: TRACK_LANGUAGE } || undefined

Result: if detail is present, changes any matching TextTrack to mode="disabled". If detail is not present, changes any TextTrack that currently has mode="showing" to mode="disabled".

Examples:


// Example 1
const track = { kind: "captions", language: "en_US", label: "English (US)" };
const evt1 = new CustomEvent("mediahidetexttracksrequest", { composed: true, bubbles: true, detail: track });
this.dispatchEvent(evt1);

// Example 2 (multi-select)
const track1 = { kind: "captions", language: "en_US" }; // Assumes this caption track has no `label`
const track2 = { kind: "subtitles", label: "English (with descriptions)", language: "en_US" };
const evt2 = new CustomEvent("mediahidetexttracksrequest", { composed: true, bubbles: true, detail: [track1, track2] });
this.dispatchEvent(evt2);

// Example 3 (disable/hide all currently showing)
const evt3 = new CustomEvent("mediahidetexttracksrequest", { composed: true, bubbles: true });
this.dispatchEvent(evt1);

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:7

github_iconTop GitHub Comments

1reaction
cjpillsburycommented, Sep 13, 2021

We tell menu-el author to send a mediahidesubtitlesrequest event. If we aren’t concerned about the performance of captions continuing to be ‘active’ after no longer needed by the user, this is the more ecosystem-friendly option.

My S1 is that this feels better because it avoids the downstream side effects that come with disabling a text track.

So after discussion we decided to go with the mediadisablesubtitlesrequest/mediadisablecaptionsrequest for the “default behavior”, for a few reasons:

  • Per @heff 's callout, there will be some performance hit (though likely negligible from a “big picture” perspective
  • network/data usage - for any cases where a dev isn’t simply adding a <track/> element for their TextTrack (e.g. text tracks defined via media groups for captions/subtitles in an HLS primary playlist), setting the tracks as “hidden” would entail fetching the data (and parsing, etc.) for each subtitle/cc. This can include tracks in e.g. fmp4/ts containers, adding even more network/data usage
  • default initial track states - by default a subtitle/cc track would actually be “disabled” and not “hidden”, so this would be the most likely “non-showing” state for baseline text track usage
  • surprise events - for users who are monitoring events from text tracks, they may be surprised to get e.g. cuechange events from tracks they weren’t intentionally having as “hidden”. If we used “hidden”, the number of tracks that would dispatch cuechange events would change over time simply based on a user interacting with the subtitles/cc select/flyaway menu

On the side of the UI-element author who creates a single menu containing both captions and subtitles tracks, psuedo-code would look like:

function showTextTrack (track) {
    let eventName
   if (track.kind === 'captions') {
     eventName = 'mediashowcaptionsrequest'
   }
   if (track.kind === 'subtitles') {
     eventName = 'mediashowsubtitlesrequest'
   }
  const evt1 = new CustomEvent(eventName, {
    composed: true, 
    bubbles: true,
    detail: encodeURIComponent(`${track.language}:${track.label}:`)
  });
}

The little bit of extra overhead comes with that conditional to figure out the right event name, not a deal breaker, and Christian mentioned another way we can work around that.

Yup. Also, for our “built in” CC/subtitle track selector, any time we choose to “show” one track, we also need to make sure we “hide” (actually disable, per ☝️) all currently showing subtitle/cc tracks. This isn’t especially more complex than your example, but it does mean we may be dispatching up to 3 events to make a transition. Not a show stopper, but worth calling out I think.

0reactions
dylanjhacommented, Sep 12, 2021

Catching up here, in the example <media-ui-el media-captions-showing="en-US:English es">, this element is a fictional, possibly future element of an external transcript element, correct?

Allowing for a “batching” use case feels like it would be handy (regardless of what particular events we settle on) and wouldn’t be especially more complex to implement than the single track case.

Agree with this 👍🏼

We tell menu-el author to send a mediahidesubtitlesrequest event. If we aren’t concerned about the performance of captions continuing to be ‘active’ after no longer needed by the user, this is the more ecosystem-friendly option.

My S1 is that this feels better because it avoids the downstream side effects that come with disabling a text track.

I don’t have a strong opinion on Kind-specific events (mediashowcaptionsrequest / mediashowsubtitlesrequest) vs. the general event (mediashowtexttrackrequest). My S1 is what Christian pointed out:

the most common media chrome element use case (and what will be our “out of box” captions/subtitles selection element) will be a component that allows showing exactly one subtitle or caption track. If our events are distinguished by kind, this adds complexity/burden to element implementors.

On the side of the UI-element author who creates a single menu containing both captions and subtitles tracks, psuedo-code would look like:

function showTextTrack (track) {
    let eventName
   if (track.kind === 'captions') {
     eventName = 'mediashowcaptionsrequest'
   }
   if (track.kind === 'subtitles') {
     eventName = 'mediashowsubtitlesrequest'
   }
  const evt1 = new CustomEvent(eventName, {
    composed: true, 
    bubbles: true,
    detail: encodeURIComponent(`${track.language}:${track.label}:`)
  });
}

The little bit of extra overhead comes with that conditional to figure out the right event name, not a deal breaker, and Christian mentioned another way we can work around that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TextTrack.mode - Web APIs | MDN
The TextTrack interface's mode property is a string specifying and controlling the text track's mode: disabled, hidden, or showing.
Read more >
Can't Control Display of Text Tracks via JS anymore? #2124
8.0 to v4.12.5 for support of some ad plugin for VideoJS but I now have noticed I can no longer control the display...
Read more >
Subtitles | AVPro Video - Documentation - RenderHeads
Get the number of text tracks int trackCount = mediaPlayer.TextTracks.GetTextTracks().Count; // Iterate through the tracks foreach (TextTrack track in ...
Read more >
Can I generate subtitles in WeVideo?
To show or hide subtitles in a product, click the “Show/Hide Subtitles” button on the right side of the ... Vtt stands for...
Read more >
Text Tracks - Video.js
Subtitles are shown over the video. "captions" : Transcription of the dialogue, sound effects, musical cues, and other audio information for viewer who...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found