下面给你 4 个常见且实用的示例:最小示例(直接设置 playbackRate)、带倍速下拉选择、带 “+ / -” 按钮 与 进度滑块,以及兼顾 保持音高 的兼容写法。代码都可以直接复制到本地运行。
示例 1 — 最小可用:直接设置倍速
<!doctype html>
<html>
<head><meta charset="utf-8"><title>简单倍速</title></head>
<body>
<video id="video" width="640" controls src="your-video.mp4"></video>
<div>
<button onclick="document.getElementById('video').playbackRate = 0.5">0.5x</button>
<button onclick="document.getElementById('video').playbackRate = 1">1x</button>
<button onclick="document.getElementById('video').playbackRate = 1.5">1.5x</button>
<button onclick="document.getElementById('video').playbackRate = 2">2x</button>
</div>
</body>
</html>
说明:HTMLMediaElement 的 playbackRate 属性控制播放速度(1 = 正常速)。这是最简单、最直接的做法。
示例 2 — 下拉选择与显示当前倍速
<!doctype html>
<html>
<head><meta charset="utf-8"><title>下拉倍速</title></head>
<body>
<video id="video" width="640" controls src="your-video.mp4"></video>
<label>倍速:
<select id="speed">
<option value="0.5">0.5x</option>
<option value="0.75">0.75x</option>
<option value="1" selected>1x</option>
<option value="1.25">1.25x</option>
<option value="1.5">1.5x</option>
<option value="2">2x</option>
</select>
</label>
<span id="cur">当前: 1x</span>
<script>
const v = document.getElementById('video');
const sel = document.getElementById('speed');
const cur = document.getElementById('cur');
sel.addEventListener('change', () => {
const rate = parseFloat(sel.value);
v.playbackRate = rate;
cur.textContent = `当前: ${rate}x`;
});
// 如果页面上其它地方修改了速率,保持 UI 同步
v.addEventListener('ratechange', () => {
cur.textContent = `当前: ${v.playbackRate}x`;
sel.value = String(v.playbackRate);
});
</script>
</body>
</html>
示例 3 — 细粒度控制:按钮 + 滑块 + 键盘快捷键
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>细粒度倍速控制</title>
<style>
.controls { margin-top: 8px; display:flex; gap:8px; align-items:center; }
</style>
</head>
<body>
<video id="video" width="640" controls src="your-video.mp4"></video>
<div class="controls">
<button id="decrease">-</button>
<input id="rateRange" type="range" min="0.25" max="3" step="0.05" value="1" />
<button id="increase">+</button>
<span id="label">1.00x</span>
</div>
<script>
const v = document.getElementById('video');
const r = document.getElementById('rateRange');
const label = document.getElementById('label');
const dec = document.getElementById('decrease');
const inc = document.getElementById('increase');
function setRate(rate) {
// 限制精度到两位小数
rate = Math.round(rate * 100) / 100;
v.playbackRate = rate;
r.value = rate;
label.textContent = rate.toFixed(2) + 'x';
}
r.addEventListener('input', () => setRate(parseFloat(r.value)));
dec.addEventListener('click', () => setRate(Math.max(0.25, parseFloat(r.value) - 0.05)));
inc.addEventListener('click', () => setRate(Math.min(3, parseFloat(r.value) + 0.05)));
// 键盘快捷:按 > 增速,按 < 减速(在页面有焦点时)
window.addEventListener('keydown', (e) => {
if (e.key === '>' || e.key === '.') setRate(Math.min(3, parseFloat(r.value) + 0.1));
if (e.key === '<' || e.key === ',') setRate(Math.max(0.25, parseFloat(r.value) - 0.1));
// 直接按数字键切换常用速度(例如按 1 -> 1x)
if (e.key >= '0' && e.key <= '9') {
const map = { '1':1, '2':1.25, '3':1.5, '4':2 };
if (map[e.key]) setRate(map[e.key]);
}
});
// 保证当视频自身改变 rate 时 UI 更新
v.addEventListener('ratechange', () => {
r.value = v.playbackRate;
label.textContent = v.playbackRate.toFixed(2) + 'x';
});
</script>
</body>
</html>
示例 4 — 关于“保持音高(preserve pitch)”与兼容写法
- 直接改变
playbackRate会改变播放速度。现代浏览器通常会保留或修正音高(即不会让声音变“尖”或“低沉”),但不同浏览器历史上有不同属性名。 - 为兼容老浏览器,你可以设置这些非标准属性(安全回退):
const v = document.getElementById('video');
// 标准:preservesPitch (不是所有浏览器都实现)
if ('preservesPitch' in v) v.preservesPitch = true;
// 历史前缀(旧版 Safari / Chrome / Firefox)
if ('webkitPreservesPitch' in v) v.webkitPreservesPitch = true;
if ('mozPreservesPitch' in v) v.mozPreservesPitch = true;
if ('msPreservesPitch' in v) v.msPreservesPitch = true;
注意:尽管大多数现代桌面浏览器会做音高修正,但在某些移动设备或非常老的浏览器上,音高可能随速率改变而产生畸变。如果对音高有严格要求(尤其是对纯音频的高质量时间伸缩),需要使用专门的音频处理库(如
soundtouch.js、wavesurfer.js的 time-stretch 插件 或 WebAudio 的更复杂实现)。
进阶提示(可选)
- 如果需要无缝从一个速率平滑过渡到另一个速率,可以用
requestAnimationFrame在短时间内逐步调整playbackRate,避免突变带来的听感不适。 - 如果你用 H5 播放直播流(HLS/DASH),某些播放器(如 video.js + playbackRate plugin)可以处理更好。
- 在移动端测试时注意:部分平台竖屏或省电策略可能影响
playbackRate行为,务必多机型测试。 - 对于音频-only 且需要高质量 time-stretch,考虑用 WebAudio + granular/time-domain algorithms 或现成库(会比直接设置
playbackRate更复杂但效果更好)。