【问题标题】:Custom progress bar for javascript audio playerjavascript音频播放器的自定义进度条
【发布时间】:2020-05-18 00:50:49
【问题描述】:

当您在其中任何一个轨道上点击播放时,我有两个轨道会加载到单个 <audio> 上。这似乎工作得很好。这些曲目中的每一个都有一个单独的 <progress> 字段,但无论您播放什么曲目,您都只会看到第一个 <progress> 字段上的进度条。

有没有办法解决这个问题?

暂停和恢复歌曲时也会出现错误。总时间和当前时间文本字段会在瞬间显示“Na”消息,然后再次显示正确的总时间/当前时间。

我怎样才能阻止这种情况发生?

HTML

<audio id="globalAudio"></audio>

<div class="mp3Player" data-src="https://www.freesound.org/data/previews/338/338825_1648170-lq.mp3" data-pos="0">
    <button class="btnPlayPause button">Play</button>
    <span class="infoLabel">
        <span id="seekObjContainer">
            <progress id="seekbar" value="0" max="1"></progress>
        </span>
        <span class="start-time"></span>
        <span class="end-time"></span>
    </span>
</div>

<div class="mp3Player" data-src="http://www.lukeduncan.me/oslo.mp3" data-pos="0">
    <button class="btnPlayPause button">Play</button>
    <span class="infoLabel">
        <span id="seekObjContainer">
            <progress class="seekbar1" value="0" max="1"></progress>
        </span>
        <span class="start-time"></span>
        <span class="end-time"></span>
    </span>
</div>

JS

var globalAudio = document.getElementById("globalAudio");
var current = null;
var playingString = "<span>Pause</span>";
var pausedString = "<span>Play</span>";
$(document.body).on('click', '.btnPlayPause', function(e) {
  var target = this;

function calculateTotalValue(length) {
  var minutes = Math.floor(length / 60),
    seconds_int = length - minutes * 60,
    seconds_str = seconds_int.toString(),
    seconds = seconds_str.substr(0, 2),
    time = minutes + ':' + seconds;

  return time;
}

function calculateCurrentValue(currentTime) {
  var current_hour = parseInt(currentTime / 3600) % 24,
    current_minute = parseInt(currentTime / 60) % 60,
    current_seconds_long = currentTime % 60,
    current_seconds = current_seconds_long.toFixed(),
    current_time = (current_minute < 10 ? "0" + current_minute : current_minute) + ":" + (current_seconds < 10 ? "0" + current_seconds : current_seconds);

  return current_time;
}

function initProgressBar() {
  var length = globalAudio.duration;
  var current_time = globalAudio.currentTime;

  var totalLength = calculateTotalValue(length);
  jQuery(".end-time").html(totalLength);
  var currentTime = calculateCurrentValue(current_time);
  jQuery(".start-time").html(currentTime);

  var progressbar = document.getElementById('seekbar');
  progressbar.value = globalAudio.currentTime / globalAudio.duration;
  console.log(target);
}

if (current == target) {
  target.innerHTML = pausedString;
  target.parentNode.setAttribute('data-pos', globalAudio.currentTime); //start from paused
  globalAudio.pause();
  current = null;
} else {
  if (current != null) {
    current.innerHTML = pausedString;
    current.parentNode.setAttribute('data-pos', '0'); //reset position
    target.parentNode.setAttribute('data-pos', globalAudio.currentTime); //start from paused
  }
  current = target;
  target.innerHTML = playingString;
  globalAudio.src = target.parentNode.getAttribute('data-src');
  globalAudio.play();
  globalAudio.onloadeddata = function() {
    globalAudio.currentTime = parseFloat(target.parentNode.getAttribute('data-pos'));
    globalAudio.addEventListener("timeupdate",function(){ initProgressBar(); });
  };
}
});

这是fiddle 中的一个工作示例

谢谢

【问题讨论】:

    标签: javascript progress-bar html5-audio current-time


    【解决方案1】:

    那是因为只有第一个 &lt;progress&gt; 标签有 id:

    <progress id="seekbar" value="0" max="1"></progress>
    <progress class="seekbar1" value="0" max="1"></progress>
    

    然后:

    var progressbar = document.getElementById('seekbar'); // <-- always getting the first progress tag
    progressbar.value = globalAudio.currentTime / globalAudio.duration;
    

    对于瞬间出现的NaN 问题,这是因为在&lt;audio&gt; 标记中加载源时,duration 在浏览器检索到文件的元数据之前是未知的。虽然这个duration 是未知的,但它的值是NaN(不是数字)。

    您可以添加支票:

    if (Number.isNaN(element.duration)) {
      // display 00:00 or whatever you want
    }
    

    【讨论】:

    • 第二个&lt;progress&gt; 也有一个ID,但它必须与第一个不同,否则任何进度条都不起作用。有没有办法让它自动化,所以我不必为每个音轨复制这个代码? var progressbar = document.getElementById('seekbar'); progressbar.value = globalAudio.currentTime / globalAudio.duration;
    • 我明白为什么它会在您第一次点击播放时显示NaN,但如果我暂停音频并再次按播放,则不需要再次拨打该电话。 This example 似乎工作正常,没有显示任何 NaN
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多