Delete a TextTrack from a video
Asked Answered
B

6

5

Is there a good way to delete a single TextTrack added via JavaScript to a HTML5 <video> tag? The following code is a simple demo of how to add a track, but I haven't found a good way to remove one:

document.querySelector('video#myVideo').addTextTrack(...);
Breezeway answered 27/3, 2015 at 17:43 Comment(1)
Give this issue a github.com/whatwg/html/issues/1921 a thumb up to raise awareness and make a PRPentastyle
I
5

There is no mechanism to remove an added text-track (probably a flaw (?) in the current specification. There is also an onremovetrack event but...).

The only thing we can do is to disable or hide it. Make sure you keep a reference to the track:

var video = document.querySelector('video#myVideo');
var track = video.addTextTrack("...");
...
track.mode = "showing";  // when cues are added and is ready

Then when you no longer need it:

track.mode = "disabled"; // or "hidden"

(you might get around resetting the src as well, but I haven't tried this..)

Immolate answered 27/3, 2015 at 21:10 Comment(2)
Yeah, that's what I am doing, I just wanted to be sure there's no way around this, for now. The only way to trigger an onremovetrack event is by removing the <track> node from the video tag, which of course is not possible for "non-DOM" tracks.Breezeway
You can add regular tracks with a <track> node, and by removing it the related element from the textTracks property is immediately removed as well.Breezeway
W
2

Implementation of TextTrackList

Please refer to this URL first if you did not read. https://developer.mozilla.org/en-US/docs/Web/API/TextTrackList

It metioned that

addtrack

Fired when a new text track has been added to the media element.

removetrack

Fired when a new text track has been removed from the media element.

As you can see from the above, addtrack and removetrack events are dependent on HTMLMediaElement.

Remove track with DOM element .removeChild()

<!-- HTML -->
<video src="foo.ogv">
    <track kind="subtitles" label="English subtitles" src="subtitles_en.vtt" srclang="en" default>
    </track>
    <track kind="subtitles" label="Deutsche Untertitel" src="subtitles_de.vtt" srclang="de">
    </track>
</video>

videoElement.textTracks console output

var videoElement = document.querySelector("video");
console.log(videoElement.textTracks);
//output
TextTrackList {0: TextTrack, 1: TextTrack, length: 2, onchange: null, onaddtrack: null, onremovetrack: null}
0: TextTrack {kind: "subtitles", label: "English subtitles", language: "en", id: "", mode: "showing", …}
1: TextTrack {kind: "subtitles", label: "Deutsche Untertitel", language: "de", id: "", mode: "disabled", …}
length: 2
videoElement.textTracks.onremovetrack = function(event){
    console.log('DOM removed',event)
    console.log(videoElement.textTracks)
}
var tracks = videoElement.querySelectorAll('track')
videoElement.removeChild(tracks[0])

//output
DOM removed TrackEvent {isTrusted: true, track: TextTrack, type: "removetrack", target: TextTrackList, currentTarget: TextTrackList, …}
TextTrackList {0: TextTrack, 1: TextTrack, length: 1,...}
0: TextTrack {kind: "subtitles", label: "Deutsche Untertitel", language: "de", id: "", mode: "disabled", …}

Disable Track

videoElement.textTracks[0].mode = "disabled"; // Disable English
videoElement.textTracks[1].mode = "showing";  // Enable Deutsche

addTextTrack & removeTextTrack

addTextTrack method will not create track element to HTMLMediaElement, thus you need to create and append track element manually if you need to remove a track using DOM element.

There is no removeTextTrack method at the moment. If you need removeTextTrack please visit the following as @Endless mentioned from the above comment. https://github.com/whatwg/html/issues/1921

Wigeon answered 11/9, 2019 at 2:16 Comment(7)
Please consider editing your answer and delete the "Remove Track" part as it might cause damage! <track> is not the only type of children <video> has, for example see this, plus textTracks might even match <track>s (if JS was used to create textTracks directly).Brightwork
@Brightwork , thank you for the suggestion. I modified the above to use videoElement.querySelectorAll('track') to avoid affect other tags.Wigeon
Thanks! But my other line missed the word "not" ("might not") - textTracks might not even match <track>s (if JS was used to create textTracks directly), so how to deal with that?Brightwork
@Brightwork , would you be able to provide a reproducible code of your issue?Wigeon
Guess you can just try w3schools.com/jsref/met_video_addtexttrack.asp while also already using HTML <track>s.Brightwork
@LWC, there is no removeTextTrack method as you know. When you use addTextTrack , you may add track element to DOM as well.Wigeon
Not having removeTextTrack is exactly why we're all here. It's a complex situation. But none of the scripts I saw online (not even MDN/W3) bothered to add HTML <track> when they used addTextTrack.Brightwork
B
1

This can be done using javascript and the VideoJS library (tested and works with 1 or more tracks):

Get the media player object in the DOM using some sort of selector, then get all it's tracks, then remove them one by one by iterating through the array in reverse order.

var player = videojs(document.getElementById(playerId));
var tracks = player.remoteTextTracks();
var numTracks = tracks.length;
for(var i = numTracks - 1; i >=0 ; i--) {
    player.removeRemoteTextTrack(tracks[i]);
}
Bookworm answered 20/12, 2019 at 3:36 Comment(3)
"remoteTextTracks is not a function"Pauper
This solution uses videojs so you need to include videojs libraries.Bookworm
I don't seem to be able to get this to work with video.js 8.x, though it worked well in 7.x versions of video.js. I get "Property 'remoteTextTracks' does not exist on type 'Player'. Did you mean 'addRemoteTextTrack'?" error.Fanlight
I
1

//best way to do this thing
//disable The Old Subtitles From The Dom
var tracks = document.querySelector("video").textTracks;
var numTracks = tracks.length;
for (var i = numTracks - 1; i >= 0; i--)
  document.querySelector("video").textTracks[i].mode = "disabled";
<video>
    <track>
    <track>
</video>
Interpellant answered 27/8, 2021 at 11:13 Comment(0)
M
0

Much more verbose, but you could use the DOM API. Most of the work is to find the correspondence between the DOM TrackElement and the TextTrack from video.textTracks.

A track added with video.addTextTrack strangely do not get added to the DOM.

Add track

const textTracksBefore = Array.from(videoElement.textTracks);
const trackElement = document.createElement('track');
trackElement.kind = 'subtitles';
trackElement.label = PlayerShakaTextDisplayer.TextTrackLabel_;
trackElement.srclang = language;
videoElement.appendChild(trackElement);
this.trackElement_ = trackElement;
const textTracksAfter = Array.from(videoElement.textTracks);
const newTracks = textTracksAfter.filter(x => !textTracksBefore.includes(x));
this.textTrack_ = newTracks[0];

Remove track

this.videoElement.removeChild(this.trackElement_);
this.trackElement_ = null;
this.textTrack_ = null;
Moore answered 18/8, 2023 at 11:12 Comment(0)
K
0

There is no removeTextTrack yet. but you can empty the cues in a TextTrack to replace them with another list of new cues by using removeCue method.

This is what I use to replace subtitles of video using javascript

    /** empty TextTrack ***/
    track = document.querySelector("video").textTracks[0];
    if (track.cues) {
      while (track.cues.length) track.removeCues(track.cues[0]);
    }
Karlsbad answered 1/7, 2024 at 13:0 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.