暂停某些 HTML5 <audio> 时发出声音

Posted

技术标签:

【中文标题】暂停某些 HTML5 <audio> 时发出声音【英文标题】:Audible popping when pausing some HTML5 <audio> 【发布时间】:2014-02-02 21:29:57 【问题描述】:

为什么在悬停状态离开时某些文件上的音频“弹出”或“点击”,而在其他文件上却没有?可以观察到弹出 here (JSFiddle)。您可能需要悬停几次,然后再悬停几次才能听到它。即使文件转换为 .ogg,它仍然会在悬停退出时弹出(尽管它的响应速度要快得多)。

var test = new Audio("test.ogg");
$('#test').hover(function() 
  test.play();
, function() 
  test.pause();
  test.currentTime = 0;
);

有没有办法解决这个问题?是音频文件本身吗?有没有办法以编程方式阻止它?

【问题讨论】:

【参考方案1】:

当您播放音频文件然后将其音量突然调为零时,“爆音”现象是不可避免的。

声音就是振动,振动被编码为声音样本中的一个值,这个值很可能不是零(比如任意值“x”)。

因此,当声音从“x”变为 0 时,这代表另一个非常短的“振动”,具有可听的音频效果。 当播放恢复时也会发生同样的事情,从 0 变为另一个“y”值(这是下一个样本中的“振动”值)。这种“运动”会产生可听见的“砰砰”声。

X 或 Y 越“远离零”,爆裂声就越响亮。这可以解释不同文件之间现象的可变性。

只有在停止时逐渐淡出(也是几毫秒)音量并在恢复时逐渐淡入才能避免这种效果。

请原谅我在语言和物理方面过于简单化,我试图让大家理解。

【讨论】:

你说的现象不适用半秒左右的效果...如果还不够,会出现在FF+Ch上,但不会出现在Sf上(我刚刚测试了最新版本那些拥有最新 mac OS 的人)... @GameAlchemist:也许 Sf 实现了(例如,像 VLC 这样的 许多 软件播放器实际上所做的)一种在停止或恢复时自行淡入和淡出的形式? 对于“短”效果:这很可能会发生,因为 THAT 声音开始和结束都平滑到零,而其他样本可能会突然开始或结束。 (或者,如果播放器未实现该淡入/淡出机制,则在您暂停 - 恢复声音时会发生这种情况)。我在混音方面有一些经验,通常的做法是剪切音频文件以插入手动在音乐记录中插入那些“淡入淡出”,当您剪切'n'粘贴音频以避免那些“流行音乐”。 这是非常有用的,我感谢你,但我将如何通过 html5/JS/jQuery/其他方式以编程方式“淡化”音频以保持悬停效果而不会弹出? 【参考方案2】:

以下代码没有使用暂停或播放,而是让声音循环播放,并在鼠标进入/离开时淡入/淡出。

淡入淡出由每 20 毫秒调用一次的函数逐步完成。此函数将减少目标体积与实际样本体积之间的差异。

http://jsfiddle.net/f9rEu/5/

var test = new Audio("http://www.sounddogs.com/previews/25/mp3/228367_SOUNDDOGS__dr.mp3");

test.loop = true ;
test.play();
fade(0);

$('#test').hover(function() 
    fade(1);
    return;
, function() 
    fade(0);
    return;
);


var targetVolume = 0;
var volumeIncrease = 0.0023 ; // in percent per millisecond

function fade( dest ) 
   targetVolume = dest ;


var lastTime = Date.now();
function fader() 
    var now= Date.now() ;
    var dt = now - lastTime ;
    lastTime = now;
    var diff = targetVolume - test.volume ;
    if (diff == 0 ) return;
    if (Math.abs ( diff )  < 5* volumeIncrease*dt ) 
        test.volume = targetVolume ;
        return ;
    
    var chg = (diff > 0) ?  volumeIncrease : - volumeIncrease ;
    chg *=  dt ;
    var newTestVolume = test.volume + chg;    
    test.volume = newTestVolume ;


setInterval(fader, 20);

编辑: 我只在桌面/Chrome 上试过,没关系,我刚刚测试过 Safari 没问题,但例如在 Firefox 上,它就一团糟。

出于好奇,我想知道是不是因为 mp3 缓冲区的处理方式,如果您使用 .wav 作为输入,声音确实很干净。 对于短循环的环境声音,.wav 是可以的。 对于更长的声音,我猜文件大小太高了。

我没有在移动设备上进行测试,但他们的音频太迟钝了,我不敢打赌......

这是一个使用 wav 的小提琴:http://jsfiddle.net/f9rEu/20/

请注意,您可能会使用 webAudio,它是一种低延迟 html5 音频 API,允许进行大量声音处理。 如果它对您定位的浏览器/设备的支持正常,您可能会在这里查看:http://caniuse.com/audio-api

【讨论】:

努力和创造概念的要点,但这实际上引入了比原来更多的弹出。我责怪 javascript/jQuery 的缓慢。 @daveycroqet 谢谢,我编辑建议一些其他方法来处理这个问题。

以上是关于暂停某些 HTML5 <audio> 时发出声音的主要内容,如果未能解决你的问题,请参考以下文章

js控制html5 audio的暂停播放停止

HTML5开发,audio 控制,当单个音频播放的时候,其它音频保持暂停状态,避免重音

HTML5中audio标签的使用

Js控制HTML5 Audio 音乐播放和关闭

暂停除已激活的玩家之外的所有其他玩家。 <audio> 元素的 jQuery 音频插件

jQuery 和 HTML 5 <audio> [关闭]