Video.js: Styling texttracks

Created on 2 Jan 2018  路  13Comments  路  Source: videojs/video.js

Seems what mentioned in #1721 was not working on version 6.6.0. Is there any way to style texttracks now? I've set HTML5 nativeTextTracks to false so that I could click Caption Settings manually on the player. Thanks in advance.

Most helpful comment

videojs 7
style captions/subtitle

.video-js .vjs-text-track-display > div > div > div{ 
    font-size: 25px !important; 
    line-height:33px !important;
    padding:5px !important;
    background:transparent !important;
    text-shadow: 1px 1px 2px #000000;
    display: inline-block !important;
}

screenshot-localhost-2018-09-09-22-29-22

screenshot-localhost-2018-09-09-22-27-24

All 13 comments

Unfortunately, we don't have a good way for developers to programmatically style text tracks. The way that Vtt.js works (the lib we use to display captions) doesn't support the ::cue pseudo selectors yet and we don't have an external API for our text track settings: https://github.com/videojs/video.js/issues/4543. The caption settings should be available though if you're not using the native text tracks as you said you are. Are you not seeing it? Or you trying to change the styles as a viewer or as a developer user of video.js?

@maobowen , traditionally it a no go, but then I really need to style it, so I hack a bit:

  1. you folk https://github.com/videojs/vtt.js to your own
  2. only keep https://github.com/videojs/video.js/blob/master/src/js/tracks/text-track-display.js#L269-L280 from text-track-display (by overwritten it)
var TextTrackDisplay = videojs.getComponent('TextTrackDisplay')

class MyTextTrackDisplay extends TextTrackDisplay {
  updateForTrack(track) {
    if (typeof window.WebVTT !== 'function' || !track.activeCues) {
      return;
    }

    const overrides = this.player_.textTrackSettings.getValues();
    const cues = [];

    for (let i = 0; i < track.activeCues.length; i++) {
      cues.push(track.activeCues[i]);
    }

    window.WebVTT.processCues(window, cues, this.el_);
    // the rest is history
  }
}

videojs.registerComponent('TextTrackDisplay', MyTextTrackDisplay)
  1. go to your vtt.js make the following change:
    scan through the lib, when ever you see document.createElement, add a class to it, and comment out all the inline styling javascript

Then style it back using css class you add to, that should do it :+1:

@gkatsev, any chance this will go to videojs ? I guess it a good thing to decouple the css part from vtt.js

Updating vttjs to use css rather than inline styles would be nice but the effort isn't trivial.

Thanks @gkatsev and @kocoten1992. The caption setting is indeed available to users by not using the native track but I just could not CSS it. @kocoten1992's way is great but I just don't want to make it so complicated at this stage, so finally I decided to return to the native track. Thanks again!

Unless I'm mistaken, text tracks can be styled through the textTrackSettings:

let player = videojs('my_video');
player.ready(function(){
    var settings = this.textTrackSettings;
    settings.setValues({
        "backgroundColor": "#000",
        "backgroundOpacity": "0",
        "edgeStyle": "uniform",
    });
    settings.updateDisplay();
});

Please upvote my stackoverflow answer if you think it is correct :)

While it's do-able, it only works for our emulated text tracks, which is basically anywhere except ios and safari.
I hope that at some point we expose it officially rather than via the component.

I changed @regisb solution a bit so that with a hook it applies to all players in my app:

videojs.hook('setup', function(player) {                                                                                                                                                                    
  var settings = player.textTrackSettings;                                                                                                                                                                  
  settings.setValues({                                                                                                                                                                                      
    "backgroundColor": "#000",                                                                                                                                                                              
    "backgroundOpacity": "0",                                                                                                                                                                               
    "edgeStyle": "uniform",                                                                                                                                                                                 
  });                                                                                                                                                                                                       
  settings.updateDisplay();                                                                                                                                                                                 
});

videojs 7
style captions/subtitle

.video-js .vjs-text-track-display > div > div > div{ 
    font-size: 25px !important; 
    line-height:33px !important;
    padding:5px !important;
    background:transparent !important;
    text-shadow: 1px 1px 2px #000000;
    display: inline-block !important;
}

screenshot-localhost-2018-09-09-22-29-22

screenshot-localhost-2018-09-09-22-27-24

I have also faced the same issue when I was needed to add padding. I have investigated a lot and found that cue can only work on following properties:

color
opacity
visibility
text-decoration
text-shadow
background
outline
font
line-height
white-space
For example :

Ex : 1
video::cue {
color:#ccc;
}

Ex : 2
video::cue {
outline:5px solid gray;
}
So we just need to apply css for video::cue to play with Caption Track Text in any Video Player

@prakashgup This worked for me. Thanks for the solution!

An alternative solution is to hook into the selectors defined in text-track-settings (these are the <select> elements in the user-facing "caption settings" window). You can programmatically adjust background/foreground color, background/foreground opacity, text edge style, font family/size, and window color/opacity.

Example:

// this changes the background color to red
const bgColorSelector = document.querySelector('.vjs-bg-color > select');
bgColorSelector.value = "#F00";

// this changes the background opacity to 0.5
const bgOpacitySelector = document.querySelector('.vjs-bg-opacity > select');
bgOpacitySelector.value = "0.5"

All of the selectors are listed in the selectConfigs object. It seems that this is the closest thing to having an official API for caption styling.

I changed @regisb solution a bit so that with a hook it applies to all players in my app:

videojs.hook('setup', function(player) {                                                                                                                                                                    
  var settings = player.textTrackSettings;                                                                                                                                                                  
  settings.setValues({                                                                                                                                                                                      
    "backgroundColor": "#000",                                                                                                                                                                              
    "backgroundOpacity": "0",                                                                                                                                                                               
    "edgeStyle": "uniform",                                                                                                                                                                                 
  });                                                                                                                                                                                                       
  settings.updateDisplay();                                                                                                                                                                                 
});

This has worked for me with 7.6

Was this page helpful?
0 / 5 - 0 ratings