如何通过CSS在HTML5视频中设置文本轨道的样式?

7bsow1i6  于 2023-05-08  发布在  HTML5
关注(0)|答案(6)|浏览(259)

是否可以在HTML5视频播放器中设置文本轨道(如字幕和标题)的样式?
我已经为Chrome找到了一种方法:

video::-webkit-media-text-track-container {
    // Style the container
}

video::-webkit-media-text-track-background {
    // Style the text background
}

video::-webkit-media-text-track-display {
    // Style the text itself
}

这似乎让Safari有点困惑。它工作,但渲染是相当bug。
但更重要的是:如何在Firefox和IE上实现这一点?

cig3rfwq

cig3rfwq1#

到目前为止,我发现的唯一跨浏览器解决方案是:隐藏视频的文本轨道,使用您自己的。
这将允许您创建自己的文本节点,包括类、ID等。然后可以通过CSS简单地对其进行样式化。
为此,您需要利用文本提示的onenter和onexit方法来实现您自己的文本节点。

var video   = document.querySelector(‘YOUR_VIDEO_SELECTOR’)
    tracks  = video.textTracks[0],
    tracks.mode = 'hidden', // must occur before cues is retrieved
    cues    = tracks.cues;

  var replaceText = function(text) {
        $('WHERE_TEXT_GETS_INSERTED').html(text);
      },

      showText = function() {
        $('WHERE_TEXT_GETS_INSERTED').show();
      },

      hideText = function() {
        $('WHERE_TEXT_GETS_INSERTED').hide();
      },

      cueEnter = function() {
        replaceText(this.text);
        showText();
      },

      cueExit = function() {
        hideText();
      },

      videoLoaded = function(e) {
        for (var i in cues) {
          var cue = cues[i];
          cue.onenter = cueEnter;
          cue.onexit = cueExit;
        }
      },

      playVideo = function(e) {
        video.play();
      };

  video.addEventListener('loadedmetadata', videoLoaded);
  video.addEventLister('load', playVideo);
  video.load();
yx2lnoni

yx2lnoni2#

在Chrome中使用:

video::cue {
  // add style here
}

火狐浏览器:
尚未支持。Open bug to implement::cue pseudo-element - https://bugzilla.mozilla.org/show_bug.cgi?id=865395

编辑:

支持Firefox,它的工作原理与Chrome和Opera类似。但目前还不支持Edge或IE。

vfhzx4xs

vfhzx4xs3#

我开始设计我的标题有一个黑色的背景,并定位在Safari和Chrome的视频下面。我已经成功地使用下面的代码,并使用下面的样式编辑.vtt文件。请注意,您必须将样式添加到.vtt文件中,否则在safari中,当视频控件(即使它们被隐藏)出现时,字幕会跳来跳去:

4
00:00:09.980 --> 00:00:12.640 line:13 position:50% align:middle 
size:100%
for just the summer but I ended up staying here.

Chrome和Safari标题的样式:
Chrome使用video::cue background-color和opacity。

video::cue {
  opacity: 1;
  background-color: black;
  font-size: 20px !important;
}

Safari使用-webkit-media-text-track-display-background作为背景色。注意!important,它覆盖了Safari固有的样式。

video::-webkit-media-text-track-display-backdrop {
  background-color: black !important;
  overflow: visible !important;
}

下面的webkit-media-text-track-display溢出允许在Chrome的标题文本周围有更多的填充:

video::-webkit-media-text-track-display {
  overflow: visible !important;
}

溢出可见在Safari的以下代码中很重要,我正在使用转换设置视频下方的标题,这依赖于固定的字体大小:

video::-webkit-media-text-track-container {
 overflow: visible !important;
 transform: translateY(30%) !important;
}

编辑
经过一些调整,我最终在我的项目中使用了这个:
重要:删除.VTT文件中的所有内联样式。
确定用户使用的是chrome还是safari。

const rootElement = document.getElementById('root');
const M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];

rootElement.className += "web";
if(M[1] === 'chrome'){
  rootElement.className += " chrome";
} else {
  rootElement.className += " safari";
}

然后在SASS .scss文件中使用以下样式。注意:如果你没有使用SASS,你可以简单地为video元素创建一个类,并嵌套相应的样式。

.chrome {
  video::cue {
    font-size: 24px;
    opacity: 1;
    background-color: black;
    -webkit-transform: translateY(10%) !important;
    transform: translateY(10%) !important;
  }

  video::-webkit-media-text-track-display {
    overflow: visible !important;
    -webkit-box-sizing: border-box;
    background: black;
    padding: 8px;
    border-radius: 16px;
  }

  video::-webkit-media-text-track-container {
    overflow: visible !important;
    -webkit-transform: translateY(40%) !important;
    transform: translateY(40%) !important;
    position: relative;
  }
}

.safari {
  video::cue {
    font-size: 24px;
    opacity: 1;
    background-color: black;
  }

  video::-webkit-media-text-track-display-backdrop {
    background-color: black !important;
    overflow: visible !important;
  }

  video::-webkit-media-text-track-display {
    overflow: visible !important;
    -webkit-box-sizing: border-box;
  }

  video::-webkit-media-text-track-container {
    overflow: visible !important;
    -webkit-transform: translateY(20%) !important;
    transform: translateY(20%) !important;
    position: absolute;
  }
}
edqdpe6u

edqdpe6u4#

这是为chrome工作的

video::-webkit-media-text-track-container {
    // Style the container
}

video::-webkit-media-text-track-background {
    // Style the text background
}

video::-webkit-media-text-track-display {
    // Style the text itself
}

你也可以从这些链接中获得一些信息。
Link 1
Link 2

ykejflvf

ykejflvf5#

联系我们

<video >
    <source ref="videoSource">
    <track default kind="subtitles" src="xxx" />
</video>

//custom element for showing subtitle
<div ref='subtitleTrackWrapper' v-show='showTextTrack'></div>

javascript

let textTrack = [your video tag].textTracks[0]
textTrack.mode = 'hidden'
textTrack.addEventListener('cuechange', () => {
const cues = textTrack.activeCues; 

    if(cues.length>0){
        this.showTextTrack = true
        this.$refs.subtitleTrackWrapper.innerHTML = cues[0].text
    }else{
        this.showTextTrack = false
    }

});
oknwwptz

oknwwptz6#

对于跨浏览器解决方案,从Spencer S.的答案中分叉,但在vanilla js中使用稍微不同的事件侦听器......

/***
  * replace subtitles for cross-browser consistency
  * from Spencer S. - https://stackoverflow.com/a/45087610/4504073
***/ 
let track  = topperVideo.textTracks[0];
track.mode = 'hidden'; // must occur before cues is retrieved
let cues    = track.cues;
let subtitleElem = topperVideoWrapper.querySelector('#topper-video-subtitle');
  
let replaceText = function(text) {
  subtitleElem.innerHTML = text;
};

let showText = function() {
  subtitleElem.style.display = "block";
};  

let trackShow = function(text) {
  replaceText(text);
  showText();
};

let trackHide = function() {
  subtitleElem.style.display = "none";
};

track.addEventListener('cuechange', function(event) {

  // test for should-be visible cue
  let activeCue = track.activeCues[0];
    
  // if would be showing a cue
  if(activeCue) {
    // get text
    let activeCueText = activeCue.text;
    // show cue
    trackShow(activeCueText);
  } else {
    // hide cue
    trackHide();
  }
});

// play video here

相关问题