3

EDIT: This has been flagged as a duplicate of How do you check if a HTML5 audio element is loaded?.

I don't think that this is a duplicate, of the above at least, because the above question regards the situation where you only want to do something after it's finished loading, and so you wait for the finished loading event. I'm talking about distinguishing between a thing that has finished loading valid data and another thing that has finished loading something invalid.

I'm simulating the blocking of mp3s on my local network, via a Squid proxy server, so that we can test for this automatically on behalf of our users, who often work in schools that have mp3-blocking firewalls (which disrupts our website).

To test whether mp3s are being blocked I have a bunch of audio tags which have a source pointing at the different domains I want to simulate being blocked, like so:

      <audio class="domain-test" controls>
        <source src="<%= url %>">
        Your browser does not support the audio element.
      </audio>    

The advantage of using an audio tag is that the src (like an img src) isn't subject to CORS restrictions, so I can try loading an mp3 from all the different domains that we use.

In the network inspector, I can see it trying to get the different urls (which are all mp3s), and I can see the response with a 403:Forbidden status, so I can see that my firewall is blocking them. If I click on the play button on the audio tag, nothing happens. So far so good: they're blocked.

But, how can I tell, in my javascript, whether it's failed? I thought that I'd be able to test the readyState of the audio tag, like so (this is in javascript with jQuery):

audioTag = $("audio.domain-test");
if(audioTag[0].readyState == 0){
  blocked = true;
}

But, the readyState is returning 4, which means "Enough data is available—and the download rate is high enough—that the media can be played through to the end without interruption." (see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState)

I think that it might be because when you try to load an mp3, the firewall shows you an html page saying "Sorry, this is blocked", and this html page is being loaded into the audio tag as its actual data, so it thinks that it's actually loaded ok. But, the data isn't actually mpeg data, so nothing happens when you press play.

What's a better way, in jQuery or native JS, to test whether the audio tag source has actually loaded properly?

At the moment I'm rendering the audio tags out onto my page, and then running my js tests on pageload, but I could generate the audio tags within my javascript, if that makes things easier.

Max Williams
  • 30,785
  • 29
  • 115
  • 186
  • 1
    Maybe [this](https://stackoverflow.com/questions/8059434/how-do-you-check-if-a-html5-audio-element-is-loaded)? – infamoustrey Dec 06 '17 at 17:19
  • I don't think that this **is** a duplicate of https://stackoverflow.com/questions/8059434/how-do-you-check-if-a-html5-audio-element-is-loaded. That other question regards the situation where you only want to do something after it's finished loading, and so you wait for the finished loading event. I'm talking about distinguishing between a thing that has finished loading valid data and another thing that has **finished loading something invalid**. – Max Williams Dec 06 '17 at 17:23
  • Agreed, that answer is for a different question. Dug through some docs and found [this](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/error). I think that's more akin to what you're looking for. – infamoustrey Dec 06 '17 at 17:30
  • @infamoustrey thanks. i just tried that, and the error event doesn't fire. I think I need to write this up again as a different question, it's just going to get ignored now. – Max Williams Dec 07 '17 at 09:17
  • @MaxWilliams also try the `abort` event. If none of these fires I'm afraid the only option is to use cors enabled content that you load via fetch/xmlhttprequest and check true content and status from there. –  Dec 07 '17 at 16:17
  • @K3N funnily enough that's what I started doing, and decided the CORS stuff was too much of a PITA! Should have stuck with it, probably... – Max Williams Dec 07 '17 at 17:07

1 Answers1

0

HTMLMediaElements have an error property that should reflect the failure to parse the content:

The HTMLMediaElement.error is the MediaError object for the most recent error, or null if there has not been an error. When an error event is received by the element, you can determine details about what happened by examining this object.

If something has been loaded (determined by an event or the readyState property) and the error property is null, the content should therefore be valid.

mmlr
  • 1,510
  • 9
  • 16