11

我是在 HTML 5 中使用音频标签的新手,我想构建一个播放器。我想在曲目标签中使用 VTT 文件进行测试,以了解隐藏式字幕如何工作。

这是我的代码:

<audio controls>
    <source src="myaudio.mp3" type="audio/mpeg">
    <track kink="caption" src="myaudio.vtt" srclang="en" label="English">
</audio>

根据我所阅读的内容,track 应该适用于音频和视频,从可访问性的角度来看,这是有道理的。没有意义的是我尝试加载它的错误:

"Text track from origin 'file://' has been blocked from loading: Not at same origin as the document, and parent of track element does not have a 'crossorigin' attribute. Origin 'null' is therefore not allowed access."

在查找 crossorigin 属性时,我得到了很多关于 CORS 以及“匿名”和“用户证书”的预期值的令人困惑的文章。尝试任何一种都会导致类似的错误。

关于为什么这不起作用的任何想法?

4

7 回答 7

15

这是一个旧帖子,但是我在谷歌搜索时遇到的第一个帖子Text track from origin 'SITE_HOSTING_TEXT_TRACK' has been blocked from loading: Not at same origin as the document, and parent of track element does not have a 'crossorigin' attribute. Origin 'SITE_HOSTING_PAGE' is therefore not allowed access.

OP 似乎在本地遇到了这个问题,他可以通过禁用 Chrome 的网络安全来解决这个问题,如上所示。但用户在从不同域访问他们的文本轨道时会更频繁地看到这一点。要在所有用户的生产环境中修复它,您需要做两件事:

  1. 将正确的 CORS 标头添加到托管 VTT 文件的站点。
  2. 将该属性添加crossorigin="anonymous"到您网站的音频/视频元素。

如果您无权访问托管视频文件的站点,您可能会被卡住。但如果你这样做,你应该添加 header Access-Control-Allow-Origin:'*'。我在这样的 Node/Express 服务器上处理它:

   var app = express()
    app.use(function (req, res, next) {
      res.header('Access-Control-Allow-Origin', '*')
      res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
      next()
    })

音频/视频元素更容易修复。在您网站的 HTML 页面中,添加以下属性。

<audio controls crossorigin="anonymous">
    <source src="myaudio.mp3" type="audio/mpeg">
    <track kink="caption" src="my_file_hosted_on_a_different_domain.vtt" srclang="en" label="English">
</audio>

我希望这个答案对某人有所帮助......这是一个令人讨厌的故障排除问题。

于 2016-05-25T20:12:15.077 回答
8

有关具有本机 WebVTT 支持的浏览器的更新列表,请参见此处。如果您的浏览器不支持原生 CC 作为 WebVTT,您必须在 JavaScript 中构建自己的解析器来显示它们(注意还有其他 CC 格式,如 SRT 和 TTML/DFXP)。

您可以在此处此处找到有关轨道元素的可靠信息。请注意,所谓的字幕、标题和描述之间存在差异。

大多数浏览器在与音频标签一起使用时不支持轨道标签 - 尽管理论上它们应该 - 你会发现实际上它在今天不起作用。也许它与 WebVTT (意思是 Web Video Text Tracks)有关。这在此处进行了描述。

如果要沿音频标签显示隐藏式字幕,则必须构建自己的解析器。我建议您查看mediaelementjs的来源,以了解如何解决此问题。

仅当您请求的 CC 文件与托管音频/视频标签的页面不在同一个域中时,才需要 CORS。在您的情况下应该没有必要。更多关于CORS的信息。

您的错误消息似乎表明您的系统某处配置错误(也许您的 vtt 文件在 NFS 上?)。

于 2014-04-24T14:25:11.480 回答
4

我一直在处理同样的问题:媒体播放器工作正常,但隐藏式字幕文件遇到跨域问题。有些浏览器会阻塞,有些则不会。某些浏览器需要特定的 CORS 策略,并且不会接受允许的来源中的通配符。这让我的生活变得复杂。

我们可以将字幕文件存储在我们的主要内容服务器上。但我们更喜欢将视频和字幕文件保存在同一位置(在我的例子中,在 Amazon Web Services S3/CloudFront 上)。为了避免 CORS 的复杂性,我们构建了一个小的服务器端脚本来从 CDN 中获取微小的字幕文件。这消除了所有跨域问题。

于 2015-06-09T14:52:53.637 回答
4

https://github.com/videogular/videogular/issues/123

将 crossorigin="anonymous" 添加到 video 标签以允许从不同域加载 VTT 文件。

这是一个奇怪的问题,即使您的 CORS 在服务器上设置正确,您也可能需要将您的 HTML 标记标签本身设置为匿名,以便 CORS 策略起作用。

于 2018-01-11T22:11:19.767 回答
2

我遇到了很多错误,我在这里列出所有错误,以防万一它对某人有帮助:

  1. 与 CORS 相关的第一个错误与他的问题中提到的 OP 完全相同。

来自“file://”的文本轨道已被阻止加载:与文档的来源不同,并且轨道元素的父级没有“crossorigin”属性。因此,Origin 'null' 不允许访问。

问题是我直接从磁盘将我的 html 文件加载到浏览器中,所以当它尝试访问 vtt 文件时,浏览器会感觉到跨源请求,因此会出现错误。只需将网页托管在 IIS 等 Web 服务器中,即可消除此错误。在 IIS 中创建网站只需 2 分钟。或者,您可以简单地在现有的“默认网站”中添加一个新应用程序,该应用程序是默认安装 IIS 时附带的。

当您开始像网站一样获取 html 页面时,所有文件(如视频或 *.vtt)都是相对的,因此 CORS 问题得到解决。

  1. 在 CORS 问题得到解决后,我开始收到 *.vtt 文件的以下错误:

加载资源失败:服务器响应状态为 404(未找到)

现在这个问题与 *.vtt 是 IIS 的未知文件类型有关,并且您的 IIS 未配置为服务器任何扩展名为 .vtt 的资源。为此,您需要在 IIS 中为您的 Web 应用程序配置 MIME 类型,详细信息如下:

File Name Extension: .vtt
MIME type: text/vtt

在此处输入图像描述

这解决了我的文件未找到错误。

  1. 现在开发人员工具控制台选项卡中没有显示任何错误,但我的字幕仍然没有显示。然后是最后一招。我忘记default在我的跟踪标签中提及属性,如下所示。浏览器必须提示选择适当的 vtt 文件:

<track label="English" kind="subtitles" srclang="en" src="./data/abc.vtt" default />

现在我的字幕终于工作了:)

于 2017-05-31T00:39:38.807 回答
2

这是我通过单独的 HTTP 调用获取 webVTT 并<track>在字幕/元数据轨道更改或呈现时将内容注入元素的 SRC 属性,从而在我的 web 组件(基于 lit-html)中实现此功能的方法:

<video class="video__player" @click=${e=> this._onVideoPress(e)}
          poster=${this.poster}
          preload="auto"
        >
          <source src=${this.URL} type="video/webm" />
          <source src=${this.URL2} type="video/mp4" />

          <track
            default
            kind="metadata"
            type="text/vtt"
            @cuechange=${e => this._doSomething(e)}
            src=${this.metadata}
          />
        </video>

  updated(changedProperties) {
    if (changedProperties.has('metadata')) {
      const tracks = this.shadowRoot.querySelectorAll('track');
      tracks.forEach(track => this.loadTrackWithAjax(track))
      }
    }
  

  // eslint-disable-next-line class-methods-use-this
  loadTrackWithAjax(track) {
    const xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
      if (this.readyState === 4 && this.status === 200 && this.responseText) {
        // If VTT fetch succeeded, replace the src with a BLOB URL.
        const blob = new Blob([this.responseText], { type: 'text/vtt' });
        track.setAttribute('src', URL.createObjectURL(blob));
      }
    };
    xhttp.open('GET', track.src, true);
    xhttp.send();
  }

我的视频和曲目存储在同一个 Firebase 存储桶中,但即使更改了 CORS 和crossorigin设置(甚至停止加载视频),浏览器也拒绝加载曲目。

于 2021-02-07T07:24:19.613 回答
0

如果您收到“404:未找到”错误,您可能需要在 Web.config 中添加以下行:

<system.webServer>
    <staticContent>
        <remove fileExtension=".vtt" /> <!--REMOVES SERVER .vtt extention if it exists-->
        <mimeMap fileExtension=".vtt" mimeType="text/vtt" /> <!--ads it again (needed when debuging)-->
    </staticContent>
</system.webServer>
</configuration>

请注意,.vtt不支持从头开始,因此 Chrome(以及其他)出于安全原因会阻止内容。

于 2018-10-21T09:08:54.380 回答