How do I send headers while setting audio src?
Asked Answered
T

1

8

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.

Tagore answered 11/12, 2020 at 11:48 Comment(8)
What did you try? What is the error message?Rephrase
what did I try? I added src to audio tag, that's what I tried! I do not know how to set a custom header for audio tags that's what I asked, what is the error message? there is no error, the question is looking for a way to achieve something I have no idea about, I have read some answers where people say it's not possibleTagore
@Rephrase I think you're confused, I am not making any request by my own, the browser is doing it when I call load(), I wanna intercept that to modify it!Tagore
A question needs a minimal reproducible example. And the for MCVE it is relevant, that it works. Otherwise it is not reproducible.Rephrase
@cerving Alright, I'll keep than in mind, thanks for editing the question!Tagore
check this out!Aardwolf
From what I understand and read from developer.mozilla.org/en-US/docs/Web/HTML/Element/audio, as of date, it is not possible to set the custom headers. Do you have control on the server side? If so, maybe make changes there to make it compatible or check if safari can insert gzip header somehowPassive
@Passive no I do not have any control server-side otherwise it would have been much easier, I guess the only way left for me is to download the entire video via js and pass it to media tagsTagore
E
4

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.

Eyeshot answered 16/12, 2020 at 11:28 Comment(4)
I do not want to download the entire file before playing.Tagore
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 where as 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, hope you got a clearer picture now...Tagore
Okay - I see you've added this clarification to your original question.👍🏽 I don't think there's a way (at the moment) to 'intercept' these requests, IMO it's better to control the fetching yourself (and thus, be sure the behaviour is what you want regardless of browser). If you don't want to download the whole file before playing, you can still possibly adapt my answer above into a stream that can be loaded and played as it's being 'piped' in. Please see here for some ideas: developer.mozilla.org/en-US/docs/Web/API/Body/arrayBufferEyeshot
I think the problem here what if the file is 100MB plus size.. it needs to download everything to play.Bombproof

© 2022 - 2024 — McMap. All rights reserved.