首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在每次击键时都能得到一个(非常)短的.mp3音频文件?

如何在每次击键时都能得到一个(非常)短的.mp3音频文件?
EN

Stack Overflow用户
提问于 2017-10-04 16:35:08
回答 2查看 687关注 0票数 4

我正在构建一个web应用程序,其中包括一个表单和(作为一个渐进的增强/用户体验效果),我想要一个按键来触发一个击键声音效果。

我已经削减了.mp3的声音效果相当短(0.18s)。

然而,当我在我的笔记本电脑上的Firefox上测试我的安装程序时,似乎出现了可听到的延迟(并不是每个按键都会触发声音效果)。

在我的Android上的Firefox Mobile上,很少有按键触发声音效果--也许每八个键中就有一个键。

我是在尝试用现在的网络技术去实现一些无法完成的事情,还是我只是简单地以错误的方式来处理这个问题呢?

这是我的设置:

代码语言:javascript
运行
复制
var myInput = document.getElementsByTagName('input')[0];
var keypress = document.getElementsByClassName('keypress')[0];

function playSoundEffect() {
    keypress.play();
}

myInput.addEventListener('keydown', playSoundEffect, false);

/* I've also tried...
myInput.addEventListener('keyup', playSoundEffect, false);
myInput.addEventListener('keypress', playSoundEffect, false);
*/
代码语言:javascript
运行
复制
input {
width: 90vw;
}
代码语言:javascript
运行
复制
<input type="text" placeholder="Type to hear the sound effect..." />

<audio class="keypress">
<source src="http://handsoffhri.org/.assets/theme/elements/mp3/keypress.mp3" type="audio/mpeg">
</audio>

第二次尝试:

由于下面来自@StackingForHeap和@zero298的有益评论,我重构了我的设置:

代码语言:javascript
运行
复制
var myInput = document.getElementsByTagName('input')[0];

function playSoundEffect() {
    var jsKeypress = new Audio('http://handsoffhri.org/.assets/theme/elements/mp3/keypress.mp3');
    jsKeypress.play();
}

myInput.addEventListener('input', playSoundEffect, false);
代码语言:javascript
运行
复制
input {
width: 90vw;
}
代码语言:javascript
运行
复制
<input type="text" placeholder="Type to hear the sound effect..." />

这无疑是一个改进--每次创建一个新的Audio对象,允许每个对象独立于以前创建的Audio对象进行播放。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-04 17:36:47

我看了你的第二次尝试,它似乎听起来很好(原谅双关语)。然而,我只是尝试了一下,我就能得到很好的结果:

这使用了我在Freesound.org: UI确认警报,C4.wav上找到的一个音频文件。

这将创建一个AudioContext,而不仅仅是一个Audio,并一次又一次地使用相同的、已经加载的缓冲区。我还在试着看看那里是否有表现上的提高。

看起来,您必须一次又一次地创建源节点:

AudioBufferSourceNode只能播放一次;每次调用start()之后,如果您想再次播放相同的声音,就必须创建一个新的节点。幸运的是,这些节点的创建成本非常低,并且实际的AudioBuffers可以用于多个声音播放。实际上,您可以以一种“火而忘”的方式使用这些节点:创建节点,调用start()开始播放声音,甚至不需要保存对它的引用。它将自动被垃圾收集在一个适当的时间,这不会是在什么时候后,声音已完成播放。

代码语言:javascript
运行
复制
/*jslint browser:true, esversion:6, devel:true*/
/*global AudioContext*/

(function() {
  "use strict";

  function main() {
    let ctx = new AudioContext();

    fetch("/res/audio/twinkle.wav")
      .then(res => res.arrayBuffer())
      .then((buffer) => {
        return new Promise((resolve, reject) => {
          ctx.decodeAudioData(buffer, (audioBuffer) => {
            resolve(audioBuffer);
          });
        });
      })
      .then((audioBuffer) => {
        document.addEventListener("keydown", (e) => {
          console.log(e.keyCode);
          if (e.keyCode === 37) { // The "left arrow" key
            let source = ctx.createBufferSource();
            source.buffer = audioBuffer;
            source.connect(ctx.destination);
            source.start(0);
          }
        });
      });
  }
  document.addEventListener("DOMContentLoaded", main);
}());

票数 1
EN

Stack Overflow用户

发布于 2017-10-04 17:06:36

我尝试对howler.js库进行相同的处理,它似乎运行得很好。这是示例

代码语言:javascript
运行
复制
 var myInput = document.getElementsByTagName('input')[0];
  var sound = new Howl({
    src:['http://handsoffhri.org/.assets/theme/elements/mp3/keypress.mp3']
  });

  sound.play();


  function playSoundEffect() {
    sound.play();
   }

  myInput.addEventListener('keydown', playSoundEffect, false);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46569903

复制
相关文章

相似问题

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