簡単なバニラの例を次に示します。
const url = "https://upload.wikimedia.org/wikipedia/en/a/a9/Webern_-_Sehr_langsam.ogg";
const audio = new Audio(url);
const playBtn = document.querySelector("button");
const progressEl = document.querySelector('input[type="range"]');
let mouseDownOnSlider = false;
audio.addEventListener("loadeddata", () => {
progressEl.value = 0;
});
audio.addEventListener("timeupdate", () => {
if (!mouseDownOnSlider) {
progressEl.value = audio.currentTime / audio.duration * 100;
}
});
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">
アプローチは、input[type="range"]
スライダーを使用して進行状況を反映し、ユーザーがトラックをシークできるようにすることです。範囲が変更されたらaudio.currentTime
、スライダーをパーセントとして使用して属性を設定します (スライダーのmax
属性を に合わせて調整することもできますaudio.duration
)。
timeupdate
もう一方の方向では、イベントの発生時にスライダーの進行状況を更新します。
1 つのまれなケースとして、ユーザーがマウスをスライダー上に置いたままスクロールすると、timeupdate
イベントが発生し続け、ユーザーのカーソルがホバリングしている場所と現在のオーディオの進行状況の間で進行状況が飛び跳ねます。これを防ぐために、スライダーでブール値とmousedown
/イベントを使用します。mouseup
時間を表示するこのコードの拡張については、JavaScript - HTML5 オーディオ / カスタム プレーヤーのシークバーと現在の時間も参照してください。