簡體   English   中英

JavaScript - HTML5 音頻/自定義播放器的搜索欄和當前時間

[英]JavaScript - HTML5 Audio / custom player's seekbar and current time

我正在開發一個自定義 HTML5 音頻播放器,但似乎我在某些時候錯過了一些東西:
<input>范圍滑塊沒有跟隨音頻,並且播放當前時間的<div>跨度不起作用 - 它正在彼此相鄰添加零。

到目前為止,這是我的代碼:

HTML

<div class="player">
    <audio id="HAE">
        <source src="https://upload.wikimedia.org/wikipedia/commons/transcoded/b/b1/Haussperling2008.ogg/Haussperling2008.ogg.mp3" type="audio/mpeg">
    </audio>
    <div id="playpause">PLAY</div>
    <input id="progress" type="range" min="0" max="100" value="0" step="0.1">
    <div id="ct">00:00</div>
</div>

JavaScript

// VARIABLES

hae = document.getElementById('HAE');
pp = document.getElementById('playpause');
progress = document.getElementById('progress');
seeking = false;
seekto = hae.duration * (progress.value / 100);
ct = document.getElementById('ct');
time = hae.currentTime * (100 / hae.duration);
mins = Math.floor(hae.currentTime / 60);
secs = Math.floor(hae.currentTime - mins * 60);

// EVENTS

pp.addEventListener('click', togglePlay);
progress.addEventListener('mousedown', function(event) {seeking = true; seek(event);});
progress.addEventListener('mousemove', function(event) {seek(event);});
progress.addEventListener('mouseup', function() {seeking = false;});
hae.addEventListener('timeupdate', function(){ seekTimeUpdate(); });


// TOGGLE PLAY/PAUSE

function togglePlay() {
    if (hae.paused) {
        hae.play();
        pp.innerHTML = "PAUSE";
    }
    else {
        hae.pause();
        pp.innerHTML = "PLAY";
    }
}

// PROGRESS BAR

function seek(event){
    if(seeking){
        progress.value = event.clientX - progress.offsetLeft;
        hae.currentTime = seekto;
    }
}

// MM:SS

function seekTimeUpdate(){
    progress.value = time;
    if(secs < 10) {secs = "0" + secs;}
    if(mins < 10) {mins = "0" + mins;}
    ct.innerHTML = mins + ":" + secs;
}

這是一個工作小提琴
有人可以幫我解決我的問題嗎?

提前致謝!

這里的基本問題是,變量time,mins,secs和seekto無法獲得音頻的currentTime屬性-它們是已定義的,但是每次調用它們時,它們始終是相同的值。 您需要的是將在現有代碼中使用實時currentTime值的getter函數。 這是一個修訂版本,保留了原始HTML和盡可能多的JavaScript:

// VARIABLES

hae = document.getElementById('HAE');
pp = document.getElementById('playpause');
progress = document.getElementById('progress');
seeking = false;
ct = document.getElementById('ct');

// FUNCTIONS

function pad(str) {
    return (parseInt(str)<10 ? '0' : '') + str;
}

audioData = {};

Object.defineProperties(audioData, {
    seekto: {
      get: function() {
          return hae.duration * (progress.value / 100);
      },
      enumerable: true,
      configurable: true
    },
    time: {
      get: function() {
          return hae.currentTime * (100 / hae.duration);
      },
      enumerable: true,
      configurable: true
    },
    mins: {
      get: function() {
          return Math.floor(hae.currentTime / 60);
      },
      enumerable: true,
      configurable: true
    },
    secs: {
      get: function() {
          return Math.floor(hae.currentTime % 60);
      },
      enumerable: true,
      configurable: true
    },
});

// EVENTS

pp.addEventListener('click', togglePlay);
progress.addEventListener('mousedown', function(event) {seeking = true; seek(event);});
progress.addEventListener('mousemove', function(event) {seek(event);});
progress.addEventListener('mouseup', function() {seeking = false;});
hae.addEventListener('timeupdate', function(){ seekTimeUpdate(); });


// TOGGLE PLAY/PAUSE

function togglePlay() {
    if (hae.paused) {
        hae.play();
        pp.innerHTML = "PAUSE";
    }
    else {
        hae.pause();
        pp.innerHTML = "PLAY";
    }
}

// PROGRESS BAR

function seek(event){
    if(seeking){
        progress.value = event.clientX - progress.offsetLeft;
        hae.currentTime = audioData.seekto;
    }
}

// CURRENT TIME

function seekTimeUpdate(){
    progress.value = audioData.time;
    ct.innerHTML = pad(audioData.mins) + ":" + pad(audioData.secs);
}

JsFiddle 在這里

secs = "0" + secs; secs "0" ,因此該字符串將隨着timeupdate事件調用seekTimeUpdate不斷增加。

從相關問題Custom progress bar for <audio> 和 <progress> HTML5 元素中的進度代碼開始(有關說明,請參閱該帖子),可以使用線程JavaScript中的格式選項之一添加時間讀數。 格式為 hh:mm:ss 的字符串 我選擇的方法使用DatetoISOString來避免擔心細節。

 const url = "https://upload.wikimedia.org/wikipedia/commons/transcoded/b/b1/Haussperling2008.ogg/Haussperling2008.ogg.mp3"; const audio = new Audio(url); const playBtn = document.querySelector("button"); const currTimeEl = document.querySelector(".current-time"); const durationEl = document.querySelector(".duration"); const progressEl = document.querySelector('input[type="range"]'); let mouseDownOnSlider = false; const fmtTime = s => { const d = new Date(0); if (s > 0) { d.setSeconds(s % 60); d.setMinutes(s / 60); } return d.toISOString().slice(14, 19); }; audio.addEventListener("loadeddata", () => { progressEl.value = 0; currTimeEl.textContent = fmtTime(audio.currentTime); durationEl.textContent = fmtTime(audio.duration); }); audio.addEventListener("timeupdate", () => { if (!mouseDownOnSlider) { progressEl.value = audio.currentTime / audio.duration * 100; currTimeEl.textContent = fmtTime(audio.currentTime); durationEl.textContent = fmtTime(audio.duration); } }); audio.addEventListener("ended", () => { playBtn.textContent = "▶️"; }); playBtn.addEventListener("click", () => { audio.paused ? audio.play() : audio.pause(); playBtn.textContent = audio.paused ? "▶️" : "⏸️"; }); progressEl.addEventListener("change", () => { const pct = progressEl.value / 100; audio.currentTime = (audio.duration || 0) * pct; }); progressEl.addEventListener("mousedown", () => { mouseDownOnSlider = true; }); progressEl.addEventListener("mouseup", () => { mouseDownOnSlider = false; });
 button { font-size: 1.5em; }
 <button>▶️</button> <input type="range" value="0" min="0" max="100" step="1"><span class="current-time">00:00</span>/<span class="duration">00:00</span>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM