当使用<audio>标签播放网页上的音频文件时,有没有办法在音频中出现单词间隙或停顿时动态加速播放,然后恢复到1x (正常)速度?
发布于 2021-07-15 16:23:40
改编the linked question中的示例
<!DOCTYPE html>
<head>
<meta charset='utf-8'>
<title>Henry Louis Gates</title>
<body>
<p><audio crossorigin='anonymous' id='audio' controls src='https://upload.wikimedia.org/wikipedia/commons/0/08/Split_infinitive.ogg' style='width: 100%'></audio>
<p><label><input id='chk-skip' type='checkbox' checked> Skip silence</label>
<p>Loudness: <meter id='meter' style='width: 15em;'></meter> <span id='label-loud' style="display: inline-block; width: 20em; text-align: right;">−∞ dB FS</span>
<p>Speed: <span id='label-fast'>1×</span>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
const audio = document.getElementById('audio');
// 2048 sample buffer, 1 channel in, 1 channel out
const meter = document.getElementById('meter');
const labelFast = document.getElementById('label-fast');
const labelLoud = document.getElementById('label-loud');
const chkSkip = document.getElementById('chk-skip');
const handler = function () {
// we only need to do this once
this.removeEventListener('play', handler);
const ctx = new AudioContext();
const processor = ctx.createScriptProcessor(2048, 1, 1);
processor.onaudioprocess = function (evt) {
const input = evt.inputBuffer.getChannelData(0);
const rms = Math.sqrt(
input.map(val => val * val).reduce((a, b) => a + b, 0)
/ input.length
);
if (chkSkip.checked) {
if (rms < 0.006) {
audio.playbackRate = 4;
} else if (rms >= 0.004) {
audio.playbackRate = 1;
}
}
function formatDecibel(val) {
val = 10 * Math.log(val) / Math.log(10);
if (val === -Infinity)
return '−∞';
if (val < 0)
return '−' + (-val).toFixed(1)
}
meter.value = rms;
labelLoud.textContent = `${formatDecibel(rms)}\xa0dB FS (LPCM RMS ${rms.toFixed(5)})`;
labelFast.textContent = `${audio.playbackRate}×`;
};
const source = ctx.createMediaElementSource(audio);
source.connect(ctx.destination);
source.connect(processor);
processor.connect(ctx.destination);
}
audio.addEventListener('play', handler, false);
}, false);
</script>
缺点:这似乎只有在基于Blink和WebKit的浏览器中才能顺利工作(同源策略偶尔会干扰)。Firefox可以播放音频并检测静音,但播放速度设置似乎没有影响。寻找到静默片段的结尾可能会更好。
此外,为了简单起见,我在这里使用了一个废弃的API;实现像静默检测器这样的过滤器的首选方法是使用a Worker thread。你可能会想看看这个。
https://stackoverflow.com/questions/68300658
复制相似问题