Reputation:
I'm trying to play an audio file using html5 audio tag.
It plays fine...
But for some reason it is required that the request browser is making for the source, must include a specific header that the browser (safari in my case) is not adding. (where as I see chrome adds)
The header is: Accept-encoding: gzip
How can I make this happen?
I do not want to download entire file beforehand... I want audio tag to handle it, with a new header.
document.getElementById("audio").load();
document.getElementById("audio").play();
<audio id="audio" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/7/7b/FurElise.ogg/FurElise.ogg.mp3"> <audio>
Once again, when this code runs, I just want to modify header for every request made for this...
Note:
When you add a source and load in let's say chrome, the browser makes 'ranged requests' asking for subsequent parts of the media file so it can start playing as soon as some data is available, however, the CDN I'm using requires those requests to have this specific header, the problem is in chrome this header is added by chrome itself whereas in safari it's not, hence I wanted to intercept these requests which browser is making when I call load()
on media element and add the header.
I do not want to download the entire file before paying it, I know that works but that defeats the purpose.
Upvotes: 8
Views: 4031
Reputation: 798
Since what you want to do is load then play, how about combinining your request with a XMLHttpRequest
style pattern, using something like fetch
?
Like:
HTML
<!-- just an indicator, in case the file is large -->
<div id="loading"><em>File is loading. Please wait...</em></div>
<!-- initially hide the audio tag. Also, change the 'src' to 'data-src' so it doesn't automatically load -->
<audio id="audio" style="display: none;" data-src="https://upload.wikimedia.org/wikipedia/commons/transcoded/7/7b/FurElise.ogg/FurElise.ogg.mp3" controls></audio>
Javascript
// define variables
var audioEl = document.getElementById("audio");
function fetchAudioFile() {
// go get the file
var requestObj = new Request(audioEl.dataset.src, {
method: 'GET',
headers: {
'Accept-encoding': 'gzip' // add your header(s)
},
referrerPolicy: 'no-referrer'
});
fetch(requestObj).then(function(response) {
return response;
}).then(async function(outcome) {
const blob = await outcome.blob();
// convert our blob to a url that can be used by the audio tag
const url = window.URL.createObjectURL(blob);
// replace the source
audioEl.src = url;
// hide the helpful text
document.getElementById("loading").style["display"] = "none";
// show the audio tag
audioEl.style["display"] = "block";
// play it immediately
audioEl.play();
});
};
// get the file
fetchAudioFile();
Hopefully this helps. Please note though that depending on the browser, sometimes the audio might not autoplay unless the user first interacts with the page or explicitly gives permission.
Upvotes: 4