Crossorigin errors when loading VTT file - html5-audio

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?

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:
Add the right CORS headers to the site hosting the VTT file.
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 crossorigin attribute.
<audio controls crossorigin="anonymous">
<source src="myaudio.mp3" type="audio/mpeg">
<track kind="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.

See here for an update list of browser with native WebVTT support. If your browser does not support native CC as WebVTT you have to construct your own parser in JavaScript to display them (note there are other CC format like SRT and TTML/DFXP).
You can find reliable information about the track element here and here. Note that there is a difference between what is referred to as subtitles, captions and descriptions.
Most browsers won't support a track tag when used with an audio tag - though in theory they should - you will find practically it does not work as of today. Maybe it has something to do with WebVTT meaning Web Video Text Tracks. This is described here.
You have to build your own parser if you want to display your closed captions along an audio tag. I would suggest you take a look at the source of mediaelementjs to get an idea on how to tackle this.
CORS is only required when you are requesting CC files that are not on the same domain as the page hosting the audio/video tag. It should not be necessary in your case. More about CORS.
Your error message seems to indicate you have a misconfiguration somewhere in your system (maybe your vtt file is on NFS?).

I've been dealing with the same issue: the media player works fine, but the closed captioning file runs into cross-domain issues. Some browsers choke, others do not. Some browsers want a specific CORS policy and will not accept a wildcard in the allowed origin. And that makes my life complicated.
We could store the caption files on our primary content server. But we prefer to maintain the video and caption files in the same location (in my case, on Amazon Web Services S3/CloudFront). To get around the CORS complications, we built a small server-side script to grab the tiny caption files from the CDN. That eliminates all cross-domain issues.

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.

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

I faced a multitude of error and I'm listing all of them here just in case if it helps someone:
First error related to CORS exactly same OP as mentioned in his question.
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.
The problem was that I was loading my html file in browser directly from disk so when it tries to access the vtt file then browser gets a feeling of cross origin request and hence the error. You can get rid of this error simply by hosting your web page inside a web server like IIS. It is a 2-minute job to create a website in IIS. Or you can simply add a new application inside the existing "Default Web site" which comes with default installation of IIS.
The moment you start fetching your html page like a website all the files like video, or *.vtt are all relative so issue of CORS gets resolved.
After CORS issue got resolved I started getting below error for *.vtt file:
Failed to load resource: the server responded with a status of 404
(Not Found)
Now this issue relates to the fact that *.vtt is an unknown file type for IIS and your IIS is not configured to server any resource with extension .vtt. For this you need to configure the MIME type for your web application in IIS with below details:
File Name Extension: .vtt
MIME type: text/vtt
This resolved my file not found error.
Now no errors were being shown in the developer tools console tab but my subtitles were still not getting shown. Then came the final trick. I had forgotten to mention default attribute in my track tag as shown below. It is a mandatory hint for the browser to pick up the appropriate vtt file:
<track label="English" kind="subtitles" srclang="en" src="./data/abc.vtt" default />
Now my subtitles finally worked :)

You might want to add the following lines in your Web.config if you get a "404: not found" error:
<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>
Note that .vtt is not supported from scratch, and thus Chrome (among others) blocks the content for security reasons.

i solve this problem using Blob !
(async () => {
const result = await axios({
url: `http://ROUTE_TO_YOUR_VTT_FILE`,
method: "get",
responseType: "blob",
});
playerRef?.addRemoteTextTrack(
{
src: URL.createObjectURL(result as Blob),
mode: "showing",
id: subtitle.languageId,
language: subtitle.languageName,
kind: "subtitles",
default: true,
label: subtitle.languageName,
srclang: subtitle.languageName,
},
true
);
})();

Related

Subtitles (TRACK tags) for VIDEO tag in HTML5

everybody.
I'm having a problem that moved discussdion in the WEB before, but by now, I can't really find an answer, of better I'm not really understanding the matter.
So, I need to add some subtitlers track to some videos, I'm studying to put in a website.
I know that video are managed in HTML5 form the VIDEO tag, and subtitles from the nested TRACK tag. Video tracks must be in the WebVTT format.
As a first experience, I created a very simple markup by applying the basic controls, using a video file in .webm format and creating 2 simple traces of subtitles (first in .srt format, then transformed into .vtt), as follows:
<source src="Kayath[1].webm" type="video/webm">
<track kind="subtitles" src="test_it.vtt" srclang="it" label="italiano" default>
<track kind="subtitles" src="test_en.vtt" srclang="en" label="english">
</video>
The .VTT tracks file are simple and I think correct. Her a beginning of one of them:
1
00:00:02.509 --> 00:00:07.509
Select "Release data download" item
2
00:00:08.045 --> 00:00:10.150
In the data download form
Now, I would like to check in local, to process and define subtitle formatting through the possibilities offered by WebVTT (at the moment each formatting code is absent), but the reproduction with Chrome gives me the following error, preventing me from the view of subtitles:
Unsafe attempt to load URL [...] from frame with URL [...] 'file:' URLs are treated as unique security origins.
I avoid reporting the URLs because the videos .webm and the .vtt are in the same folder.
A similar behavior is also found in Firefox, where the aforementioned error is not reported in the console, but the vtt tracks also do not appear.
With another browser (Vivaldi, Chrome-based) also an error is showed in console at the page loading, but it's different:
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.
So, it seems to say that a local works with .vtt files is impossible (but .webm work correctly).
In Stackoverflow, I found some answers, but I'm really surprised that there aren't any way to work locally, just to help with the VTT formatting definition.
Has anyone a solution, or I really must put files in a local server to test them?

Track tag not working

I am trying to make demo with track tag but track tag is not working from below code my video play only but subtitle is now show on screen
<!DOCTYPE html>
<html>
<head>
<title>track</title>
</head>
<body>
<video autoplay="true" controls="" >
<source src="http://www.html5rocks.com/en/tutorials/track/basics/treeOfLife/video/developerStories-en.webm" type="video/webm; codecs="vp8, vorbis"">
<track src="http://www.html5rocks.com/en/tutorials/track/basics/treeOfLife/tracks/developerStories-subtitles-en.vtt" label="English subtitles" kind="subtitles" srclang="en" default=""></track>
</video>
</body>
</html>
Text tracks are subject to Cross Origin Resource Sharing, which means two things in this case:
Your <video> element must have the crossorigin attribute.
The text track source must be served with proper CORS headers.
In this case, the html5rocks site has not enabled any CORS headers for the subtitles, so you won't be able to use them.
1) Make sure to use .vtt subtitle files. If not there convert using some online tool.
2) Use kind="captions"
3) Run over localhost using xampp...like software
I got the same problem recently. You have to make sure that
The extension of track file should be .vtt (as told in earlier answers)
Imp. Make sure that the file is loading into the browser successfully.
To do that, right click and click, inspect element and go to console tab.
Do you see here a message saying "Unsafe attempt to load URL ..."? resolve that.
One of the way of doing that is,
keep the .vtt file in same directory as of index.html
Run the file on some local server. ( you may use any extension, like live server for visual studio code.)
This wil enable browser to load both file and security issue will be arised.

HTML5 video loop doesn't work on Chrome (Sitefinity CMS)

I ran into this peculiar problem that I couldn't get HTML5 video to loop on my local development environment (ASP.NET + IIS7). The video autoplays just fine. My code looks like this:
<video id="frontpage-video" autoplay loop>
<source src="http://test-site:8084/video_mp4.mp4" type="video/mp4">
<source src="http://test-site:8084/video_webm.webm" type="video/webm">
</video>
If I change video source URLs to some publicly available URLs (for example to dropbox), loop works just fine. This is not a major problem since I think (hope) it will work once my site goes live and the video is publicly available.
My question is: Can I make the video loop if my video is not publicly available?
I couldn't find similar problems by googling. Could it be some kind of IIS setting that prevents videos to loop?
Update 1: The problem seems to occur only in Chrome. Firefox and IE works fine.
Update 2: It seems that the video will stop at the end but never returns true for element.ended
> document.getElementById('frontpage-video').duration;
< 16.12
> document.getElementById('frontpage-video').currentTime;
< 16.12
> document.getElementById('frontpage-video').ended;
< false
Update 3: Problem is either in IIS or in Telerik's Sitefinity CMS. Server should send a "206 Partial Content" status but instead it sends 200 OK. Has any Sitefinity users had this problem and know how to solve it?
It looks like your problem is that you're not using HTTP Byte Serving. Your server is sending a "200 OK" response, but it should be sending "206 Partial Content" along with these headers:
Accept-Ranges:bytes
Content-Range:bytes 0-1492370/1492371
The byte range request allows the browser to request only the portions of the file that it needs. So if you seek around, it can skip right to that point.
With the regular 200 response, you will usually at least find that you can't seek in the video. But, depending on how your video file is encoded and where in the file the metadata is placed, you may see more problems. Sometimes the file might not even play at all. WebM is usually more robust than MP4, which can be all over the place.
I don't know IIS well enough to tell you how to configure it, but try starting here:
http://blogs.visigo.com/chriscoulson/easy-handling-of-http-range-requests-in-asp-net/
Chrome/Opera can't loop the video if the video itself is not served with HTTP 206 Partial Content response but 200 OK instead.
The problem is that Sitefinity's storage providers do not support partial content (version 7.0). They are planning to implement this for the future.
At the moment the possible workaround is to use an external blob storage provider such as Azure, Amazon or ExternalFileSystem (ExternalFileSystemStorageProvider).
I got this information from Sitefinity's support team.
May be MIME type in IIS is not set up for MP4.
Open IIS, and locate you default page. You'll see MIME type in right pane.
Click Add and put field1=.mp4 and field2=video/mp4.
Restart IIS.
Hope this might work.
In your question, your video-element doesn't have the id frontpage-video (but i guess it's copy paste?)
check if the video end event is called in your webkit browsers, and if so, restart your video.
.
<script type='text/javascript'>
document.getElementById('frontpage-video').addEventListener('ended',myHandler,false);
function myHandler(e) {
if(!e) { e = window.event; }
//restart your video
}

Html5 video track data uri

I want to set <track src to a "data:" URI.
<video>
<source src="http://the.othersite/foo.mp4">
<track src="data:text/vtt,WEBVTT">
</video>
However, I get
Cross-origin text track load denied by Cross-Origin Resource Sharing policy.
The error occurs in both Chrome and Safari.
If I set track src to "/foo.vtt", it works. The "Origin" of Data URI is not the current page uri?
Jsfiddle example here. (Look at the error output in the Console.)
Browser support for setting the track data via data URIs appears to be incomplete and buggy. Here is a list of bug reports for each browser.
Firefox appears to support setting track directly in the HTML using base64 encoded data URIs (jsfiddle). Updating the track src via JavaScript appears to work but doesn't appear to affect that actual track data that is in use.
If you really need to update the track data via JavaScript, you can manually parse the WEBVTT text and add it a Cue at-a-time. This page describes all the methods that don't work for including VTT data directly in the page and gives an example of parsing and Cue loading at the end.

cross-origin video in Safari

Does anyone know if Safari supports crossorigin attribute on the HTML5 <video> tag? I serve video from a server that responds with all needed CORS headers, and I use the markup below to embed the video to my page. The page is served from a different domain.
<video controls crossorigin="anonymous" src="http://example.com/movie.mp4">
I then draw the video to a canvas and get the image from the canvas using toDataURL API. This works in Chrome and Firefox, but Safari throws the security error as if there were no crossorigin attribute on the video.
Any ideas?
It appears that Safari does not support the crossorgin attribute, but I can't find anything official. There is this tweet https://twitter.com/sonnypiers/status/187513545397776384 with a work-around for images, but I don't think it helps for video.
From our tests we safari did not support crossdomain. We are adding crossorigin attribute to use CORs in audio requests (will report how does that goes).
Funny how crossdomain seemed to work fine under http but not under https. If you read the w3 spec for audio/video tags (called media tags) it does say they subjected to cross-domain restrictions.
Support of CORS in audio tag:
https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes
Now, other interesting fact is that safari was choosing the myme type based on the file extension (what?). A file with *.mp4 as an extension played fine. Same file renamed to something else did not.
Here's the workaround for video:
$.ajax({
type: 'get',
url : videoUrlFromAnotherDomain,
crossDomain: 'true',
success: function(data) {
// get a base64 version of the video!
var base64 = window.btoa(data);
// get a new url!
var newURL = 'data:video/mp4' + ';base64,' + base64;
// set the src on the video source element to the new url
video.find("source").attr("src", newURL);
}
Substitute whatever type of video it is for "video/mp4" in newURL.
At first, do you need CORS?
Linking to it directly seems to work in safari. I tried it using htmlinstant.com
<video src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" controls />
If you need CORS, then the following page says that support for it was added in May 2011. Haven't tested it though.
https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes
For an example with video on canvas, see section 5.4 at this link:
http://www.html5rocks.com/en/tutorials/video/basics/
I tested and it runs in my safari.