Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crossorigin errors when loading VTT file

I'm new to using the audio tag in HTML 5 and wanted to build a player. I wanted to test using a VTT file in a track tag to see how closed captioning could work.

Here is my code:

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

According to what I've read, track is supposed to work for both audio and video, which makes sense from an accessibility stand-point. What doesn't make sense is the error I get trying to load it:

"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."

When looking up the crossorigin attribute, I get a lot of confusing articles about CORS and the expected values of "anonymous" and "user-certificate". Trying either results in a similar error.

Any ideas as to why this won't work?

like image 595
linnium Avatar asked Apr 23 '14 23:04

linnium


People also ask

Which player can play VTT files?

vtt files. These files are also compatible with popular media players like VLC and GOM Player. While they're primarily associated with Google Chrome, they work just as well with any popular web browser.

Is VTT a text file?

VTT files are text files saved in Video Text Tracks format, also known as WebVTT. This type of file contains information about the video (such as metadata) and is one of the most common file formats used in video subtitling nowadays.


3 Answers

This is an old post, but the first I hit when Googling for 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.

The OP seems to be having this issue locally and he could fix that by disabling Chrome's web security as shown above. But users will more often see this when accessing their text tracks from a different domain. To fix it in a production environment for all users, you need to do two things:

  1. Add the right CORS headers to the site hosting the VTT file.
  2. Add the crossorigin="anonymous" attribute to your site's audio/video element.

If you do not have access to the site hosting the video file, you might be stuck. But if you do, you should add the header Access-Control-Allow-Origin:'*'. I'm handling it on a Node/Express server like this:

   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()
    })

The audio/video element is an easier fix. In your site's HTML page, add the following attribute.

<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>

I hope this answer helps someone... it was an annoying issue to troubleshoot.

like image 106
TimHayes Avatar answered Oct 11 '22 07:10

TimHayes


Here's how I get this working in my web-component (lit-html based) by fetching the webVTT via a seperate HTTP call and injecting the content into the SRC property of the <track> element whenever the subtitle/metadata track changes or is rendered:

<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();
  }

My videos and tracks are stored in the same firebase storage bucket but the browser refused to load the tracks even when changing the CORS and crossorigin settings (which stopped even the videos from loading).

like image 29
Davie Avatar answered Oct 11 '22 06:10

Davie


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

Add crossorigin="anonymous" to the video tag to allow load VTT files from different domains.

It is a strange issue, even if your CORS is set correctly on the server, you may need to have your HTML tag label itself as anonymous for the CORS policy to work.

like image 35
Ray Foss Avatar answered Oct 11 '22 06:10

Ray Foss