【问题标题】:Ionic 3: playing an Icecast/Shoutcast audio streamIonic 3:播放 Icecast/Shoutcast 音频流
【发布时间】:2019-02-09 13:37:13
【问题描述】:

我正在使用 Ionic 3 框架开发一个互联网广播应用程序。我想出了这个使用 HTML5 音频元素的简单代码。许多人认为这种方法比使用 @ionic-native/streaming-media 插件更好。

以下是我的实现:

HTML

<audio id="audioStream" src="http://icecastserverIP:8000/icecastchannel" autoplay></audio>

<a href="#" id="player">
  <div class="btn-play" id="con-btn-play">
    <img src="assets/img/btn-play.png" alt="Play">
  </div>
</a>

JS

$(document).ready(function(){

    var audio = $('#audioStream')[0]


    // Preloader animation

    audio.addEventListener('waiting', function () {
        $('#con-btn-play').html('<img src="assets/img/preloader.gif">');
    }, false);
    audio.addEventListener('playing', function () {
        $('#con-btn-play').html('<img src="assets/img/btn-pause.png">');
    }, false);


    // Play button behaviour

    $('#player').click(function(){
        if (audio.paused){
            audio.play();
            $('#con-btn-play').html('<img src="assets/img/btn-pause.png" alt="Pause">');
        }else {
            audio.pause();
            $('#con-btn-play').html('<img src="assets/imgs/btn-play.png" alt="Play">');
        }
    });

});

该流在 Android 和 iOS 中可以正常播放。但是,只要有轻微的连接中断,音频就会停止并且不会重新连接。更不用说如果我按下暂停,流将继续在后台使用数据。

我的问题是:有没有更好的方法来处理 Icecast 流?您会推荐一个第三方插件以获得更好的缓冲管理和播放体验吗?

【问题讨论】:

  • 如果您有兴趣,我有基于 MediaSource Extensions 的代码,您可以为商业项目授权。请随时通过 brad@audiopump.co 与我联系。否则,请参阅下面的答案,以开始自己实施类似的事情。

标签: javascript html ionic-framework audio-streaming icecast


【解决方案1】:

但是,在最轻微的连接中断时,音频将停止并且不会重新连接。

您可以通过处理 Audio 元素上的 error 事件来重新连接您自己的代码。 https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/onerror

更不用说如果我按下暂停,流将继续在后台使用数据。

是的,您需要制作自己的 UI 来控制此元素。当有人暂停时,您需要致电 .stop()。默认情况下,音频元素假定一个在某个点结束的常规音频文件。

第三方插件...

不需要插件。

...更好的缓冲管理和播放体验?

通过我在此答案中提出的两个建议,您可以为您的用户提供有用的体验。但是,您可能会遇到另外两个尚未涉及的问题。

首先是浏览器不请求常规 ICY 元数据,也不对其进行解码。

第二个问题是,由于浏览器将您的流视为常规音频文件,因此它还将所有音频数据缓冲到内存中。这对于您永远不会返回并播放以前播放的音频的实时流来说不是很有用。 (这不是您遇到的问题,因为音频数据需要的内存相对较少,但问题确实存在。)

这两个问题都可以通过使用MediaSource Extensions 解决。使用 MSE,您可以直接控制检索数据、解复用元数据以及将数据推送到缓冲区以进行回放。由于您的代码处于控制之中,因此您可以无限期地进行流式传输,而不会发生内存泄漏。

【讨论】:

  • 谢谢布拉德!如果您指的是 Icecast/Shoutcast 元数据,我使用的是 WaveStreaming (jquery.shoutcast.js) 中的人完成的插件。唯一的问题是在歌曲更改时没有正确同步,但正如您所说,此时这并不重要。
  • 你说的.stop()是什么?我只梦想过这样的简单
  • @miknik 啊,对不起!我刚刚意识到这是在我自己的一些代码中。我现在手边没有它,但我相信我正在破坏音频元素。稍后我会再次检查。
  • 没错,我检查了HTML音频标签上不存在.stop()属性。如果您能与我们分享一个公共回购或一些代码 sn-p,我将不胜感激。非常感谢布拉德!
  • 如果有问题的 Icecast 服务器运行 2.4.2 或更高版本,您还可以在 /status-json.xsl?mount=/mountpointname 查询 JSON api 以获取当前元数据。请注意,这表示服务器上该精确时间点的元数据。客户端缓冲可能意味着您的播放时间点偏移了多达 60 秒。
【解决方案2】:

我建议的第一件事是在您的 Icecast 服务器设置中增加 &lt;queue-size&gt;&lt;burst-size&gt; 的值。

默认情况下,当客户端连接时,服务器只会将 64kb 的音频流作为缓冲区发送给客户端,对于 320kbps 的 mp3 流来说,这不到 2 秒。

&lt;audio&gt; 元素的预加载标签设置为 none 或元数据应防止在暂停时无休止的数据流,或者您可以将 playbackRate 参数设置为 0.0 或将 src 更改为空值,然后调用 @音频元素上的 987654327@ 用于在暂停时断开客户端与流的连接。

通过在连接时添加额外的请求标头,可以让 Icecast 服务器将元数据直接编码到音频流中。其优点是可以轻松地将元数据更新与音频同步。

我编写了一个基本的服务工作者脚本来处理这个过程,它将必要的标头添加到请求中,然后解析返回的流以提取元数据并创建一个仅包含传递给音频元素的音频数据的可读流.

代码在 Github here,如果你想试试的话。

【讨论】:

    猜你喜欢
    • 2014-06-04
    • 2019-03-11
    • 1970-01-01
    • 2013-08-25
    • 2013-06-05
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    相关资源
    最近更新 更多