首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用javascript动态加速音频播放中的单词间隙?

如何用javascript动态加速音频播放中的单词间隙?
EN

Stack Overflow用户
提问于 2021-07-08 19:20:34
回答 1查看 170关注 0票数 1

当使用<audio>标签播放网页上的音频文件时,有没有办法在音频中出现单词间隙或停顿时动态加速播放,然后恢复到1x (正常)速度?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-15 16:23:40

改编the linked question中的示例

代码语言:javascript
复制
<!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。你可能会想看看这个。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68300658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档