【问题标题】:networkState, readyState not working for audio streamnetworkState,readyState 不适用于音频流
【发布时间】:2019-05-13 02:08:15
【问题描述】:

我正在尝试检查音频流,看看它是否处于活动状态。服务器已打开并正在流式传输音频,或者它已关闭且未进行流式传输。我发现了两种方法,.networkState 和 .readyState,它们适用于音频标签或 Audio() 对象。当流关闭并且从未被收听(不在浏览器缓存中)时,事情看起来还不错。我每 4 秒执行一次这两种方法来捕捉流状态的任何变化,因为我想持续监控任何变化并更新网页。

问题是,一旦流的状态发生变化,即从关闭到打开或从打开到关闭,我都无法正确更新流的状态。我必须刷新页面才能获得真正的更新。然后,在您收听了流并被缓存后,它始终显示为“开启”。

为什么这两种方法都不能正确检测到流的变化?有没有办法强制检查实际对象而不是缓存对象?

(请原谅我的代码 - 我很快就把它分块了,我是一个新手)(我尝试了比下面显示的更多,但试图让这篇文章简洁。)

<script>
var myTimerVar = setInterval(myTimer, 4000);
var myFunctionVar = setInterval(myFunction, 4000);
// var aud = new Audio('http://myserver.com:8080/live.mp3');

function myTimer() {
    var acheck = document.getElementById("myAudio").networkState;
    if (acheck == 1) {
      document.getElementById("netstate").innerHTML = "ONLINE " + acheck;
      document.getElementById("netstate").style.backgroundColor = "MediumSeaGreen";
    }
    else if (acheck == 3) {
      document.getElementById("netstate").innerHTML = "OFFLINE " + acheck;
      document.getElementById("netstate").style.backgroundColor = "yellow";
    }
}

function myFunction() {
    var x = document.getElementById("myAudio").readyState;
    if (x == 0) {
      document.getElementById("readystate").innerHTML = "OFFLINE " + x;
      document.getElementById("readystate").style.backgroundColor = "yellow";
    }
    else if (x == 4) {
      document.getElementById("readystate").innerHTML = "ONLINE " + x;
      document.getElementById("readystate").style.backgroundColor = "MediumSeaGreen";
    }
}
</script>
<audio id="myAudio" controls>
  <source src="http://myserver.com:8080/live.mp3" type="audio/mpeg">
</audio>

<!-- this is what does not update correctly on the page -->
<p>StreamN0 is: <span id="netstate">OFFLINE</span></p>
<p>StreamR0 is: <span id="readystate">OFFLINE</span></p>

【问题讨论】:

    标签: javascript streaming audio-streaming internet-radio


    【解决方案1】:

    我有两个方法每 4 秒执行一次,以捕捉流状态的任何变化

    首先,考虑改用readystatechange 事件。

    const readyStates = {
      0: 'HAVE_NOTHING',
      1: 'HAVE_METADATA',
      2: 'HAVE_CURRENT_DATA',
      3: 'HAVE_FUTURE_DATA',
      4: 'HAVE_ENOUGH_DATA'
    }
    
    document.querySelector('audio#myAudio').addEventListener('readystatechange', (e) => {
      document.querySelector('#readyState').innerText = readyStates[e.readyState];
    });
    

    问题是,一旦流的状态发生变化,即从关闭到打开或从打开到关闭,我都无法正确更新流的状态。

    认为您要问的是该流是否实际上是实时的……在线与否。这不是readyState 所表示的。浏览器实际上并不知道您正在播放直播。它假定它缓存的数据是打算播放的。 readyStateHAVE_ENOUGH_DATA (4) 仅表示浏览器认为它已充分缓冲媒体,而它的缓冲速率意味着它认为它可以 continue to play without interruption

    您可能正在寻找的活动包括:

    【讨论】:

    • 我什么也做不了。我不确定它是否适用于所有情况。就像如果流不在线并且用户加载页面,那么 2 分钟后流会上线。它会在没有用户交互的情况下检测这两种状态吗?另外,你能解释一下这个“readyStates[e.readyState]”吗?我不理解“readyState”的语法或连接。
    • @Justin 不,当然它不会检测到您的流在 2 分钟后何时上线。这根本不是页面上播放器的责任。这取决于您的代码是否要重试。您将播放器的状态及其当前流与服务器上资源的状态混为一谈。他们不是一回事。对于readyStates[e.readyState] 的语法,我所做的只是记录状态的名称而不是其整数值。
    • 感谢 Brad 澄清将玩家状态和资源状态混为一谈 - 非常有帮助。我所说的readyStates[] 语法的意思是语法是如何工作的。我知道它正在改变页面内容。我无法在“e”(readyStates 的返回值)和“readyState”(跨度 ID)之间建立联系。我无法从您的示例代码中得到任何反应。而且,“.networkState”在这里根本不合适吗?
    • 可以肯定的是,我确实在我的代码setInterval 中进行了重试,以尝试在任何给定时间检测流状态。而且,“.networkState”在这里根本不合适吗?
    • @Justin 你想在页面上具体展示什么?如果您只想测试流,可以通过 Fetch API 发出HEAD 请求以确定基本状态。如果您的应用程序需要实时确定您的流是否启动并运行,您实际上可以通过服务器发送事件 (SSE) 向客户端推送状态更新。
    猜你喜欢
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多