9

I'm having trouble getting static content (mp3 files) served by an Icecast server to play in Google Chrome browser with HTML5. The reason we're serving the mp3s via Icecast is policy: the CPB requires they be "streamed" and not "downloaded" since we're public radio. Our live audio streams play just fine in Chrome.

If you put the URL for an MP3 served by my Icecast 2.4.3 server straight into the URL bar in google Chrome, it does not play. Do the same thing in Firefox, IE, Safari, etc.. it plays! Try it:

https://streaming.kansaspublicradio.org:8001/mp3/First_0713886.mp3

(The temporary solution I'm using is Flash but the latest update to Chrome (v60.0) makes Flash blocked by default, the "Always allow for this website" option does not seem to be working, and the little icon showing that Flash is blocked is much more discrete. Try it here: http://kansaspublicradio.org/kpr-news/midwest-farmers-hope-boost-online-grocery-shopping )

My best guess as to why this is happening is that it has something to do with this: https://developers.google.com/web/updates/2016/03/play-returns-promise?hl=en

So I tried to reproduce their code example, in which they monkey with HTML5 Media Capture to get audio to play without user interaction. But with this URL for the audio, it fails to play and throws this error: Uncaught (in promise) DOMException: The element has no supported sources. Try it: https://jsfiddle.net/wo94xohr/2/ It only fails in Chrome and not Firefox or others.

I tried again but without the HTML5 Media Capture stuff. Still no dice. Try it: https://jsfiddle.net/yrhets74/

Also, if you look at the response headers, you see "Content-Range:bytes 0-0/0"... could this mean something?


UPDATE: I'm testing to see if this is a CORS (cross origin resource sharing) issue. I've updated the jsfiddle to:

var audioElement = document.querySelector('#music');
audioElement.crossOrigin = "anonymous"; // CORS access restriction. Worth a shot but no dice
audioElement.type = "audio/mpeg"; // just in case? idk
audioElement.src = "https://streaming.kansaspublicradio.org:8001/mp3/First_0713886.mp3";

function startPlayback() {
  // .play() is a Promise
  return audioElement.play().then(function(x){console.log('yay!')}, function(reason){
      console.log('Error: ' + reason);
  });
}
var playButton = document.querySelector('#play');
playButton.addEventListener('click', startPlayback);

It hasn't changed the end result on Chrome, but on Firefox it doesn't play now and it gives the warning: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://streaming.kansaspublicradio.org:8001/mp3/First_0713886.mp3. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Do you think the Icecast server needs the 'Access-Control-Allow-Origin' header set to 'allow' or something?

Here's the full response from the Icecast server:

Request URL:https://streaming.kansaspublicradio.org:8001/mp3/First_0713886.mp3
Request Method:GET
Status Code:206 Partial Content
Remote Address:129.237.213.244:8001
Referrer Policy:no-referrer-when-downgrade

Response Headers
view source
Accept-Ranges:bytes
Cache-Control:no-cache
Content-Length:526408
Content-Range:bytes 0-0/0
Content-Type:audio/mpeg
Date:Tue, 15 Aug 2017 19:34:23 GMT
Expires:Mon, 26 Jul 1997 05:00:00 GMT
Pragma:no-cache
Server:Icecast 2.4.3

Request Headers
view source
Accept:*/*
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:en-US,en;q=0.8,ms;q=0.6
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:streaming.kansaspublicradio.org:8001
Origin:https://fiddle.jshell.net
Pragma:no-cache
Range:bytes=0-
Referer:https://fiddle.jshell.net/_display/
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

UPDATE 2: We've added the CORS header Access-Control-Allow-Origin:* to the icecast server's response headers and now the jsfiddle works in Firefox - no CORS header ‘Access-Control-Allow-Origin’ missing warning. Still does not play in Chrome though :(

I also tested WAV files and M3U files and neither will play in Chrome. Firefox could play the wav file (with the JSfiddle code) but no the m3u file

Dan Mantyla
  • 1,840
  • 1
  • 22
  • 33
  • 1
    You should know that there's no difference between "streamed" and "downloaded", and that your implementation of such a restriction is adding no sense of security or prevention of downloading in any way. The assertion that serving this stuff statically with Icecast is somehow different than any other webserver is false. For other CPB stations I've worked with, the client-side distinction of streaming vs. downloading was the key to the requirement. Some basic restrictions (such as signed URLs with an expiration date) went a long ways towards demonstrating best effort security. – Brad Aug 16 '17 at 00:34
  • thank you @Brad and you're right of course. If you put the URL of the MP3 directly into the browser's address bar, hit enter, and then hit Ctrl+s, the mp3 is downloaded and saved to the machine. But then why is it behaving different than mp3s served by apache?? *sigh* – Dan Mantyla Aug 16 '17 at 14:34
  • 1
    @DanMantyla Have you seen the answer here by bobince? Worth a shot https://stackoverflow.com/questions/2743279/how-could-i-play-a-shoutcast-icecast-stream-using-html5 – Martin Dawson Aug 17 '17 at 18:55
  • thanks @MartinDawson I tried it but it didn't work – Dan Mantyla Aug 17 '17 at 21:17

2 Answers2

3

I think the issue is with your stream. Here is a slightly modified example with another streaming URL:

audioElement.src = "http://novazz.ice.infomaniak.ch/novazz-128.mp3";

https://jsfiddle.net/yrhets74/5/

This works on my machine with Firefox 55 and Chrome 60.

VLC tells me the codec used is MPEG Audio 1/2 (mpga).

Regarding the CORS policy, you may be interested in this question: DOMException: Failed to load because no supported source was found

pyb
  • 4,813
  • 2
  • 27
  • 45
  • yes it's a problem with the way the server is serving the file to Chrome – Dan Mantyla Aug 18 '17 at 20:45
  • ...or the way we're encoding it – Dan Mantyla Aug 18 '17 at 20:46
  • I took an mp3 that was playing fine when served by apache, put it on the icecast server and now it doesn't play in Chrome. http://streaming.kansaspublicradio.org:8000/clip2.mp3 – Dan Mantyla Aug 18 '17 at 21:38
  • @DanMantyla Thanks for the bounty. Honestly, I think I do not deserve it as we still don't know why Chrome can't play your MP3 file. Your tests with Apache suggests there's a difference in the HTTP response. You could play with a proxy like [Burp](https://portswigger.net/burp) or maybe even Postman to see which HTTP headers matter. – pyb Aug 23 '17 at 19:20
  • it was the closest thing to a correct answer, even though it wasn't as helpful as we both hoped. The other answer wasn't correct, and the bounty was set to expire today – Dan Mantyla Aug 23 '17 at 20:16
2

Chrome is likely to play audio files with standards BitRate 128 , 160 , 320 , 512 , ...

I'm not 100% on the specifics of this, however, it looks like some MP3s using older versions of Lame, or longer than a couple of minutes, or at high (300 <) or low (128 >=) bitrates seem to be affected. It appears to be webkit-related, as it also affects Safari users.

HOWEVER!

As a solution, re-encoding the MP3 files using 160Kbps bitrate, and the latest version of LAME (3.99.5) seems to have fixed this, and they now play normally across all major browsers again. enter link description here

Mp3 File Properties

Farhad Bagherlo
  • 6,725
  • 3
  • 25
  • 47
  • did you copy that answer from here? https://stackoverflow.com/questions/32441979/google-chrome-no-longer-plays-certain-audio-files – Dan Mantyla Aug 18 '17 at 20:20
  • Sorry I forgot to give a reference. But I did my own review of your files – Farhad Bagherlo Aug 18 '17 at 20:28
  • I don't think that's the problem because I put the same mp3 on an apache server and it played fine. http://kansaspublicradio.org/widgets/First_0713886.mp3 – Dan Mantyla Aug 18 '17 at 20:44
  • Perhaps because the server uses https, this will create the problem in the Chrome security layers. I propose for you once to try the standard file. – Farhad Bagherlo Aug 18 '17 at 20:54
  • I put a 128 bit rate MP3 file on the icecast server and it's still not playing in chrome. Both https and http. http://streaming.kansaspublicradio.org:8000/clip2.mp3 – Dan Mantyla Aug 22 '17 at 14:45
  • Make a url without a port (**:8001**) on the same server – Farhad Bagherlo Aug 22 '17 at 20:59