首页 > 解决方案 > HTML元素在控制台中显示提示,但长度 = 0,并且无法通过索引访问它们

问题描述

我正在处理带有视频播放器的页面,我试图在其中显示 vtt 字幕并从<track>元素中的提示中获取信息。

以下是 HTML 中与播放器相关的内容:

<div class="video">
  <video id="vid">
    <source src="Video.mp4" type="video/mp4">
    <track kind="subtitles" src="Captions.vtt" srclang="en">
  </video>
</div>

我首先在我的 JavaScript 中有类似的东西,只是为了在操作代码中的任何内容之前看看我得到了什么。

var trackObject = $('track')[0].track;
trackObject.mode = 'showing';

console.log('Track cues:');
console.log(trackObject.cues);
console.log(trackObject.cues[0]);

对属性的更改mode是在那里完成的,因为如果我设置default<track>HTML 中的元素,那么视频不会出现在许多浏览器中。还是不知道为什么。

打印到控制台的内容如下:

在此处输入图像描述

但是,当我展开 时TextTrackCueList,我确实看到了提示:

在此处输入图像描述

在此处输入图像描述

length如果我假设提示已加载到元素中,但属性尚未更新,这对我来说才有意义。但我仍然不知道我在列表末尾看到的那个长度是多少,它显示了实际的线索数量。

我没有在文本轨道上找到任何类型的加载事件,所以我这样做是为了确保我能得到提示:

var trackObject = $('track')[0].track;
trackObject.mode = 'showing';

var waitForCues = setInterval(function() {
  if (trackObject.cues.length > 0) {
    var cueList = getTracks(trackObject)
    // ...Do some processing with the cues...
    clearInterval(waitForCues);
  }

}, 40);

为什么lengthtrack 元素的属性会发生这种情况?我怎样才能摆脱等待长度大于 0 的情况?

标签: javascripthtml

解决方案


作为 HTMLMediaElement,该<track>元素支持与任何其他 HTMLElement 相同的全局loaderror事件,因此您可以侦听这些事件以确定您的 VTT 是否已准备好开展业务。

mytrack.addEventListener(`load`, evt => {
  console.log(`good to go`);
  const { track } = mytrack;
  // force this track to become active so we can get the cues:
  track.mode = "showing";
  const { cues } = track;
  console.log(`${cues.length} cues found`);
});

mytrack.addEventListener(`error`, evt => {
  console.log(`yeah that's a problem`);
});
  <video controls>
    <source src="https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4" type="video/mp4">
    <track
           id="mytrack"
           kind="captions"
           src="data:text/plain;charset=utf-8,WEBVTT%0A%0A00%3A00%3A00.500%20--%3E%2000%3A00%3A02.000%0AThe%20Web%20is%20always%20changing%0A%0A00%3A00%3A02.500%20--%3E%2000%3A00%3A04.300%0Aand%20the%20way%20we%20access%20it%20is%20changing"
           srclang="en"
           label="English"
           default="default">
    >
  </video>


推荐阅读