HTML5 Audio
概述
HTML5 的 <audio> 元素提供了在网页中嵌入音频的标准方式,无需依赖第三方插件。
基本语法
html
<audio src="music.mp3" controls>
您的浏览器不支持 audio 标签。
</audio>音频属性
controls
显示音频控件:
html
<audio src="music.mp3" controls></audio>autoplay
自动播放(注意:大多数浏览器限制自动播放):
html
<audio src="music.mp3" autoplay></audio>loop
循环播放:
html
<audio src="music.mp3" loop controls></audio>muted
静音:
html
<audio src="music.mp3" muted controls></audio>preload
预加载策略:
html
<!-- none: 不预加载 -->
<audio src="music.mp3" preload="none" controls></audio>
<!-- metadata: 只预加载元数据 -->
<audio src="music.mp3" preload="metadata" controls></audio>
<!-- auto: 预加载整个音频 -->
<audio src="music.mp3" preload="auto" controls></audio>多格式支持
为了确保跨浏览器兼容性,提供多种音频格式:
html
<audio controls>
<source src="music.mp3" type="audio/mpeg">
<source src="music.ogg" type="audio/ogg">
<source src="music.wav" type="audio/wav">
您的浏览器不支持 audio 标签。
</audio>音频格式
| 格式 | MIME 类型 | 文件扩展名 | 浏览器支持 |
|---|---|---|---|
| MP3 | audio/mpeg | .mp3 | 广泛支持 |
| Ogg Vorbis | audio/ogg | .ogg | Firefox, Opera, Chrome |
| WAV | audio/wav | .wav | 广泛支持 |
| AAC | audio/aac | .aac | Safari, Chrome |
完整属性示例
html
<audio
src="music.mp3"
controls
autoplay
loop
muted
preload="auto">
您的浏览器不支持 audio 标签。
</audio>JavaScript 控制
基本控制
html
<audio id="myAudio">
<source src="music.mp3" type="audio/mpeg">
</audio>
<button onclick="playAudio()">播放</button>
<button onclick="pauseAudio()">暂停</button>
<button onclick="stopAudio()">停止</button>
<script>
var audio = document.getElementById("myAudio");
function playAudio() {
audio.play();
}
function pauseAudio() {
audio.pause();
}
function stopAudio() {
audio.pause();
audio.currentTime = 0;
}
</script>音量控制
html
<audio id="myAudio" src="music.mp3"></audio>
<button onclick="setVolume(0.1)">10%</button>
<button onclick="setVolume(0.5)">50%</button>
<button onclick="setVolume(1.0)">100%</button>
<script>
var audio = document.getElementById("myAudio");
function setVolume(volume) {
audio.volume = volume;
}
</script>播放速度控制
html
<audio id="myAudio" src="music.mp3" controls></audio>
<button onclick="changeSpeed(0.5)">0.5x</button>
<button onclick="changeSpeed(1.0)">1.0x</button>
<button onclick="changeSpeed(1.5)">1.5x</button>
<button onclick="changeSpeed(2.0)">2.0x</button>
<script>
var audio = document.getElementById("myAudio");
function changeSpeed(speed) {
audio.playbackRate = speed;
}
</script>音频事件
html
<audio id="myAudio" src="music.mp3" controls></audio>
<p id="status"></p>
<script>
var audio = document.getElementById("myAudio");
var status = document.getElementById("status");
audio.addEventListener("play", function() {
status.textContent = "音频正在播放";
});
audio.addEventListener("pause", function() {
status.textContent = "音频已暂停";
});
audio.addEventListener("ended", function() {
status.textContent = "音频播放结束";
});
audio.addEventListener("timeupdate", function() {
var current = Math.floor(audio.currentTime);
var duration = Math.floor(audio.duration);
status.textContent = `播放进度: ${current}秒 / ${duration}秒`;
});
audio.addEventListener("volumechange", function() {
status.textContent = `音量: ${Math.floor(audio.volume * 100)}%`;
});
</script>自定义音频播放器
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自定义音频播放器</title>
<style>
.audio-player {
max-width: 500px;
margin: 50px auto;
background-color: #f0f0f0;
border-radius: 10px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.song-info {
text-align: center;
margin-bottom: 20px;
}
.song-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 5px;
}
.song-artist {
color: #666;
}
.progress-container {
background-color: #ddd;
height: 8px;
border-radius: 4px;
cursor: pointer;
margin-bottom: 15px;
}
.progress {
background-color: #4CAF50;
height: 100%;
border-radius: 4px;
width: 0%;
transition: width 0.1s;
}
.time-info {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #666;
margin-bottom: 15px;
}
.controls {
display: flex;
justify-content: center;
align-items: center;
gap: 15px;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #45a049;
}
.volume-control {
display: flex;
align-items: center;
gap: 10px;
margin-top: 15px;
}
input[type="range"] {
flex-grow: 1;
}
</style>
</head>
<body>
<div class="audio-player">
<audio id="audio">
<source src="music.mp3" type="audio/mpeg">
</audio>
<div class="song-info">
<div class="song-title">歌曲名称</div>
<div class="song-artist">艺术家</div>
</div>
<div class="progress-container" id="progressContainer">
<div class="progress" id="progress"></div>
</div>
<div class="time-info">
<span id="currentTime">0:00</span>
<span id="duration">0:00</span>
</div>
<div class="controls">
<button id="prev">上一首</button>
<button id="playPause">播放</button>
<button id="next">下一首</button>
</div>
<div class="volume-control">
<span>🔊</span>
<input type="range" id="volume" min="0" max="100" value="100">
<span id="volumeValue">100%</span>
</div>
</div>
<script>
const audio = document.getElementById('audio');
const playPause = document.getElementById('playPause');
const progressContainer = document.getElementById('progressContainer');
const progress = document.getElementById('progress');
const currentTimeEl = document.getElementById('currentTime');
const durationEl = document.getElementById('duration');
const volumeSlider = document.getElementById('volume');
const volumeValue = document.getElementById('volumeValue');
// 播放/暂停
playPause.addEventListener('click', () => {
if (audio.paused) {
audio.play();
playPause.textContent = '暂停';
} else {
audio.pause();
playPause.textContent = '播放';
}
});
// 更新进度
audio.addEventListener('timeupdate', () => {
const percent = (audio.currentTime / audio.duration) * 100;
progress.style.width = percent + '%';
currentTimeEl.textContent = formatTime(audio.currentTime);
});
// 加载元数据
audio.addEventListener('loadedmetadata', () => {
durationEl.textContent = formatTime(audio.duration);
});
// 点击进度条
progressContainer.addEventListener('click', (e) => {
const rect = progressContainer.getBoundingClientRect();
const percent = (e.clientX - rect.left) / rect.width;
audio.currentTime = percent * audio.duration;
});
// 音量控制
volumeSlider.addEventListener('input', (e) => {
const volume = e.target.value / 100;
audio.volume = volume;
volumeValue.textContent = e.target.value + '%';
});
// 格式化时间
function formatTime(seconds) {
const min = Math.floor(seconds / 60);
const sec = Math.floor(seconds % 60);
return `${min}:${sec.toString().padStart(2, '0')}`;
}
// 播放结束
audio.addEventListener('ended', () => {
playPause.textContent = '播放';
});
</script>
</body>
</html>播放列表
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>音频播放列表</title>
<style>
.playlist {
max-width: 400px;
margin: 20px auto;
}
.playlist-item {
padding: 10px;
border-bottom: 1px solid #ddd;
cursor: pointer;
}
.playlist-item:hover {
background-color: #f0f0f0;
}
.playlist-item.active {
background-color: #4CAF50;
color: white;
}
</style>
</head>
<body>
<audio id="audio" controls></audio>
<div class="playlist">
<div class="playlist-item" data-src="song1.mp3">歌曲 1</div>
<div class="playlist-item" data-src="song2.mp3">歌曲 2</div>
<div class="playlist-item" data-src="song3.mp3">歌曲 3</div>
</div>
<script>
const audio = document.getElementById('audio');
const items = document.querySelectorAll('.playlist-item');
items.forEach(item => {
item.addEventListener('click', function() {
// 移除所有 active 类
items.forEach(i => i.classList.remove('active'));
// 添加 active 类到当前项
this.classList.add('active');
// 播放选中的音频
audio.src = this.dataset.src;
audio.play();
});
});
// 自动播放下一首
audio.addEventListener('ended', () => {
const current = document.querySelector('.playlist-item.active');
const next = current.nextElementSibling;
if (next && next.classList.contains('playlist-item')) {
next.click();
}
});
</script>
</body>
</html>音频可视化
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>音频可视化</title>
<style>
canvas {
display: block;
margin: 20px auto;
background-color: #000;
}
</style>
</head>
<body>
<audio id="audio" src="music.mp3" controls></audio>
<canvas id="canvas" width="800" height="200"></canvas>
<script>
const audio = document.getElementById('audio');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const analyser = audioContext.createAnalyser();
const source = audioContext.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioContext.destination);
analyser.fftSize = 256;
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
function draw() {
requestAnimationFrame(draw);
analyser.getByteFrequencyData(dataArray);
ctx.fillStyle = 'rgb(0, 0, 0)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
const barWidth = (canvas.width / bufferLength) * 2.5;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
const barHeight = dataArray[i] / 2;
ctx.fillStyle = `rgb(${barHeight + 100}, 50, 50)`;
ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
audio.addEventListener('play', () => {
audioContext.resume();
draw();
});
</script>
</body>
</html>最佳实践
- 提供多种格式:确保跨浏览器兼容性
- 避免自动播放:尊重用户体验
- 优化文件大小:压缩音频文件
- 提供控件:让用户控制播放
- 考虑移动设备:注意带宽和电池消耗
- 提供替代内容:为不支持的浏览器提供说明
- 使用适当的预加载策略:平衡性能和用户体验
总结
HTML5 Audio 元素为网页音频播放提供了强大的功能。通过合理使用其属性和 JavaScript API,可以创建功能丰富的音频播放体验,从简单的背景音乐到复杂的音频播放器和可视化效果。