HTML DOM Audio played 属性(建议收藏)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3700+ 小伙伴加入学习 ,欢迎点击围观
在现代 Web 开发中,音频控制功能是许多项目的核心需求,无论是在线音乐平台、视频网站还是交互式游戏,开发者都需要精准控制音频的播放状态。本文将深入探讨 HTML DOM Audio played 属性
,这一属性能够帮助开发者获取音频已播放的时间范围,从而实现进度条同步、播放进度记录等功能。通过结合实例代码和实用技巧,我们将会从基础概念逐步深入,帮助读者掌握这一属性的使用场景与技术细节。
一、基础概念:HTML Audio 元素与 DOM 属性
在讲解 played 属性
之前,我们需要先了解 HTML 中音频元素的基本知识。
1.1 HTML Audio 元素
HTML 的 <audio>
标签用于在网页中嵌入音频文件。通过结合 JavaScript 的 DOM(文档对象模型),我们可以动态控制音频的播放、暂停、音量调整等行为。例如:
<audio id="myAudio">
<source src="example.mp3" type="audio/mpeg">
</audio>
通过 JavaScript,可以获取该元素并操作其属性:
const audio = document.getElementById("myAudio");
audio.play(); // 播放音频
1.2 TimeRanges 对象与播放范围
played 属性
返回一个 TimeRanges
对象,该对象描述了音频中已被播放的时间范围。例如,如果用户在音频播放到第 3 秒时暂停,然后跳转到第 5 秒继续播放,played
将记录两个时间段:0-3秒
和 5秒之后播放的部分
。
比喻:可以将
TimeRanges
想象为一张地图,标记出音频已“探索”过的区域。
二、核心知识点:深入理解 played 属性
2.1 属性的基本用法
played 属性
是只读属性,直接通过 audioElement.played
获取。例如:
const playedRanges = audio.played;
console.log(playedRanges); // 输出 TimeRanges 对象
2.2 TimeRanges 对象的结构
TimeRanges
对象包含以下关键属性和方法:
length
:表示时间段的数量。start(index)
:返回第index
个时间段的起始时间(秒)。end(index)
:返回第index
个时间段的结束时间(秒)。
示例代码
const audio = document.getElementById("myAudio");
const played = audio.played;
if (played.length > 0) {
const firstSegmentStart = played.start(0);
const firstSegmentEnd = played.end(0);
console.log(`已播放的第一个时间段:${firstSegmentStart} 秒到 ${firstSegmentEnd} 秒`);
}
2.3 典型场景:音频进度条同步
在实际开发中,最常见的用途是同步音频播放进度条。例如,当用户拖动进度条时,需要根据已播放的时间范围更新 UI。
实现步骤
- 监听音频的
timeupdate
事件,实时获取播放进度。 - 通过
played
属性计算已播放的总时长。 - 更新进度条的样式或数值。
完整代码示例
<!-- HTML 结构 -->
<audio id="audioPlayer" src="song.mp3"></audio>
<div id="progressBar">
<div id="playedBar"></div>
</div>
<script>
const audio = document.getElementById("audioPlayer");
const progressBar = document.getElementById("progressBar");
const playedBar = document.getElementById("playedBar");
// 更新进度条
const updateProgress = () => {
const duration = audio.duration;
const played = audio.played;
if (played.length > 0) {
const endTime = played.end(played.length - 1);
const percentage = (endTime / duration) * 100;
playedBar.style.width = `${percentage}%`;
}
};
// 监听时间更新事件
audio.addEventListener("timeupdate", updateProgress);
</script>
三、进阶技巧与注意事项
3.1 处理不连续的播放记录
当用户暂停、跳转或重复播放时,played
可能包含多个时间段。例如:
- 用户播放到第 5 秒后暂停。
- 重新播放到第 8 秒后再次暂停。
此时,played
将记录两个时间段:0-5秒
和8秒之后播放的部分
。
计算总已播放时长
若需获取总已播放时长(非连续时间段的总和),可通过循环遍历 TimeRanges
:
const calculateTotalPlayed = (timeRanges) => {
let total = 0;
for (let i = 0; i < timeRanges.length; i++) {
total += timeRanges.end(i) - timeRanges.start(i);
}
return total;
};
const totalPlayedTime = calculateTotalPlayed(audio.played);
3.2 处理跨域音频资源
如果音频文件来自不同域,浏览器的安全策略可能导致 played
属性无法正确返回数据。此时需确保服务器配置了正确的 CORS(跨源资源共享)头。
3.3 性能优化建议
频繁读取 played
属性可能影响性能,建议结合 requestAnimationFrame
或 setTimeout
降低更新频率:
let rafID;
const updateProgress = () => {
// 更新逻辑
rafID = requestAnimationFrame(updateProgress);
};
// 在需要停止更新时调用
cancelAnimationFrame(rafID);
四、实际案例:实现带跳转功能的音频控制器
以下是一个综合案例,展示如何结合 played
属性实现以下功能:
- 显示当前播放进度和总时长。
- 拖动进度条跳转到指定时间点。
- 高亮显示已播放的部分。
HTML 结构
<audio id="audioPlayer" src="song.mp3"></audio>
<div class="control-container">
<button id="playPause">播放</button>
<div class="progress-bar">
<div class="progress-played"></div>
<div class="progress-buffered"></div>
<div class="progress-handle"></div>
</div>
<div class="time-display">
<span id="currentTime">00:00</span> / <span id="duration">00:00</span>
</div>
</div>
JavaScript 实现
const audio = document.getElementById("audioPlayer");
const playPauseBtn = document.getElementById("playPause");
const progressBar = document.querySelector(".progress-bar");
const progressPlayed = document.querySelector(".progress-played");
const progressHandle = document.querySelector(".progress-handle");
const currentTimeDisplay = document.getElementById("currentTime");
const durationDisplay = document.getElementById("duration");
// 初始化总时长
audio.addEventListener("loadedmetadata", () => {
durationDisplay.textContent = formatTime(audio.duration);
});
// 格式化时间(如将 123 秒转为 "02:03")
const formatTime = (seconds) => {
const minutes = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
};
// 更新进度条和时间
const updateProgress = () => {
const duration = audio.duration;
const played = audio.played;
if (played.length > 0) {
const endTime = played.end(played.length - 1);
const percentage = (endTime / duration) * 100;
progressPlayed.style.width = `${percentage}%`;
currentTimeDisplay.textContent = formatTime(endTime);
}
};
// 播放/暂停切换
playPauseBtn.addEventListener("click", () => {
if (audio.paused) {
audio.play();
playPauseBtn.textContent = "暂停";
} else {
audio.pause();
playPauseBtn.textContent = "播放";
}
});
// 拖动进度条跳转
progressBar.addEventListener("click", (e) => {
const rect = progressBar.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const percentage = clickX / progressBar.offsetWidth;
const time = percentage * audio.duration;
audio.currentTime = time;
});
// 监听事件
audio.addEventListener("timeupdate", updateProgress);
五、常见问题与解决方案
5.1 为什么 played.length
始终为 0?
- 可能原因:音频未加载完成或未开始播放。
- 解决方案:在
loadedmetadata
或canplay
事件后操作played
属性。
5.2 如何区分已缓冲与已播放的区域?
- 使用
audio.buffered
属性获取已缓冲的时间范围,与played
结合使用:const buffered = audio.buffered; // 绘制缓冲进度条的逻辑
5.3 如何避免因网络延迟导致的播放中断?
- 结合
played
和buffered
属性,当已播放区域接近缓冲末尾时,可提示用户加载更多数据。
六、结论
通过本文的学习,读者应已掌握 HTML DOM Audio played 属性
的核心功能与使用技巧。这一属性不仅是实现音频进度控制的基础,还能与 buffered
、seeked
等属性结合,构建更复杂的交互逻辑。在实际开发中,建议结合代码示例逐步调试,并关注浏览器兼容性与性能优化。掌握 played 属性
的开发者,能够更灵活地应对音频播放相关的 Web 开发需求,为用户提供流畅的交互体验。
延伸思考:尝试将
played
属性与 Web Storage 结合,记录用户的播放进度,实现“断点续播”功能。