是否可以在 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 有点困惑。它可以工作,但是渲染有很多错误。
但更重要的是:如何在 Firefox 和 IE 上实现这一点?
迄今为止我发现的唯一跨浏览器解决方案是: 隐藏视频的文本轨道并使用您自己的。
这将允许您创建自己的文本节点,包含类、id 等,然后可以简单地通过 css 设置样式。
为此,您将利用文本提示的 onenter 和 oneexit 方法来实现您自己的文本节点。
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();
将此用于 Chrome:
video::cue {
// add style here
}
火狐:
尚不支持。打开 bug 来实现 ::cue 伪元素 - https://bugzilla.mozilla.org/show_bug.cgi?id=865395
编辑:
可以支持 FireFox,其工作方式与 Chrome 和 Opera 类似。但尚不支持 Edge 或 IE。
我开始将字幕设计为黑色背景,并位于 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 背景颜色和不透明度。
video::cue {
opacity: 1;
background-color: black;
font-size: 20px !important;
}
Safari 使用 -webkit-media-text-track-display-backdrop 作为背景颜色。请注意 !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,您可以简单地为视频元素创建一个类并嵌套相应的样式。
.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;
}
}
html
<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
}
});
对于跨浏览器解决方案,从 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
经过一番研究,我对这个解决方案有所了解,您可以根据需要设置字幕样式。
var subTrack = document.getElementById("video").textTracks[0];
const customSubtitles = document.getElementById("customSubtitles")
subTrack.oncuechange = function(e) {
var cue = this.activeCues[0];
if(cue){
customSubtitles.innerHTML = cue.text
}
}
如果您想隐藏原始字幕,请将轨道类型设置为“元数据”。