繁体   English   中英

如何在每次按键时播放(非常)短的.mp3音频文件?

[英]How can I get a (very) short .mp3 audio file to play on every keystroke?

我正在构建一个包含表单和(作为渐进增强/ UX效果)的web应用程序,我想要一个按键来触发按键音效。

我将.mp3音效切得很短(0.18s)。

然而,当我在笔记本电脑上测试我在Firefox上的设置时,似乎有一个可听见的延迟(而不是每个按键都会触发声音效果)。

在我的Android上的Firefox Mobile上,很少有按键发出声音效果 - 可能每八个按键一次。

我是否正在努力实现使用现有网络技术无法实现的目标,或者我只是以错误的方式接近这一点?

这是我的设置:

 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); */ 
 input { width: 90vw; } 
 <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下面的有用评论,我已经重构了我的设置:

 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); 
 input { width: 90vw; } 
 <input type="text" placeholder="Type to hear the sound effect..." /> 

这绝对是一种改进 - 每次创建一个新的Audio对象允许每个人独立于任何先前创建的Audio对象开始播放。

我尝试使用howler.js库执行相同的过程,它似乎工作得很好。 这是一个例子

 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);

我已经看了你的第二次尝试,看起来很合理(请原谅双关语)。 但是,我只是对它进行了一次破解,我能够得到相当不错的结果:

这使用我在Freesound.org上找到的音频文件:UI Confirmation Alert,C4.wav

这会创建一个AudioContext而不仅仅是一个Audio ,并反复使用相同的,已加载的缓冲区。 我还在试着看看那里是否有性能提升。

看起来你必须一遍又一遍地制作源节点:

AudioBufferSourceNode只能播放一次; 每次调用start() ,如果要再次播放相同的声音,则必须创建一个新节点。 幸运的是,这些节点的创建成本非常低廉,实际的AudioBuffers可以重复用于多次播放声音。 实际上,您可以以“即发即忘”的方式使用这些节点:创建节点,调用start()以开始播放声音,甚至不用费心去保持对它的引用。 它将在适当的时间自动进行垃圾收集,直到声音播放结束后的某个时间才会收集。

 /*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); }()); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM