来自 Icecast 服务器的音频未在 Chrome 中播放

Audio from Icecast server not playing in Chrome

我在使用 HTML5 在 Google Chrome 浏览器中获取由 Icecast 服务器提供的静态内容(mp3 文件)时遇到问题。我们通过 Icecast 提供 mp3 的原因是政策:CPB 要求它们是 "streamed" 而不是 "downloaded" 因为我们是 public 电台。我们的实时音频流在 Chrome 中播放得很好。

如果您将我的 Icecast 2.4.3 服务器提供的 MP3 的 URL 直接放入 google Chrome 中的 URL 栏,它不会播放.在 Firefox、IE、Safari 等中做同样的事情。它播放!试一试:

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

(我使用的临时解决方案是 Flash 但最近更新到 Chrome (v60.0) 使 Flash 默认被阻止,"Always allow for this website" 选项似乎不起作用,并且显示 Flash 被阻止的小图标更加离散。在此处尝试:http://kansaspublicradio.org/kpr-news/midwest-farmers-hope-boost-online-grocery-shopping )

关于为什么会发生这种情况,我最好的猜测是它与此有关:https://developers.google.com/web/updates/2016/03/play-returns-promise?hl=en

所以我尝试重现他们的代码示例,其中他们使用 HTML5 Media Capture 来获取音频,无需用户交互即可播放。但是 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/ 它只在 Chrome 而不是 Firefox 或其他人中失败。

我又试了一次,但没有 HTML5 Media Capture 东西。仍然没有骰子。试一试:https://jsfiddle.net/yrhets74/

此外,如果您查看 header 的响应,您会看到 "Content-Range:bytes 0-0/0"... 这是否意味着什么?


更新: 我正在测试这是否是 CORS(跨源资源共享)问题。我已将 the jsfiddle 更新为:

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

它没有改变 Chrome 上的最终结果,但在 Firefox 上它现在无法播放并发出警告: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).

您认为 Icecast 服务器需要将 'Access-Control-Allow-Origin' header 设置为 'allow' 还是什么?

这是来自 Icecast 服务器的完整响应:

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

更新 2: 我们已经将 CORS header Access-Control-Allow-Origin:* 添加到 icecast 服务器的响应 headers 中,现在 jsfiddle 可以工作了在 Firefox 中 - 没有 CORS header ‘Access-Control-Allow-Origin’ missing 警告。虽然仍然没有在 Chrome 中播放 :(

我还测试了 WAV 文件和 M3U 文件,但都无法在 Chrome 中播放。 Firefox 可以播放 wav 文件(使用 JSfiddle 代码)但不能播放 m3u 文件

我认为问题出在您的信息流上。这是一个稍微修改过的示例,其中包含另一个流 URL:

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

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

这适用于我装有 Firefox 55 和 Chrome 60 的机器。

VLC 告诉我使用的编解码器是 MPEG Audio 1/2 (mpga)。

关于CORS策略,你可能对这个问题感兴趣:

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

我不是 100% 了解这方面的细节,但是,它看起来像一些 MP3 使用旧版本的 Lame,或者超过几分钟,或者高 (300 <) 或低 (128 > =) 比特率似乎受到影响。它似乎与 webkit 相关,因为它也会影响 Safari 用户。

然而!

作为解决方案,使用 160Kbps 比特率重新编码 MP3 文件,最新版本的 LAME (3.99.5) 似乎已经解决了这个问题,现在它们可以在所有主要浏览器上正常播放了。