javascript - 我如何使用从 audioContext 创建的分析器来检测是否可以听到播放的声音?

标签 javascript html html5-audio web-audio-api

首先我会描述我的问题,我正在从随机歌曲创建一个自动播放列表,一些歌曲在歌曲结束时有 10-15 秒的静音,我想要实现的是检测当一首歌曲静默 5 秒时从分析器中获取并据此采取行动。

到目前为止我得到了这个:

var context, analyser, source, audio;
context = new (window.AudioContext || window.webkitAudioContext)();
analyser = context.createAnalyser();
audio = new Audio();

source = context.createMediaElementSource(audio)
source.connect(analyser);
analyser.connect(context.destination);

var playNext = function() {
    var pickedSong;
    // chooses a song from an api with several 
    // thousands of songs and store it in pickedSong
    audio.src = pickedSong;
    audio.play();
}

audio.addEventListener('ended', playNext);

playNext();

我知道答案在分析器的某个地方,但我没有发现它返回的数据有任何一致性。

我可以这样做:

var frequencies = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(frequencies);

频率 var 将包含 2048 个键,每个键都有一个随机(对我而言)数字(-48.11、-55、-67 等),这些数字是否意味着与播放的感知声音相关的任何内容? ,我如何检测它是否足够低以至于人们会认为没有播放。

对于检测我主要想要这样的东西:

var isInSilence = function(){
    return !audible;
}

var tries = 0;

var checker = function() {
    tries = isInSilence() ? tries + 1 : 0;
    if(tries >= 5) playNext();
    setTimeout(checker, 1000);
}

checker();

唯一缺少的部分是检测歌曲当前是否静音,我们将不胜感激。

编辑:

根据 william 的回答,我设法通过这种方式解决了这个问题:

var context, compressor, gain, source, audio;
context = new (window.AudioContext || window.webkitAudioContext)();
compressor = context.createDynamicsCompressor();
gain = context.createGain();
audio = new Audio();

source = context.createMediaElementSource(audio)

// Connecting source directly
source.connect(context.destination);

// Connecting source the the compresor -> muted gain
source.connect(compressor);
compressor.connect(gain);
gain.connect(context.destination);

gain.gain.value = 0; // muting the gain
compressor.threshold.value = -100;

var playNext = function() {
    var pickedSong;
    // chooses a song from an api with several 
    // thousands of songs and store it in pickedSong
    audio.src = pickedSong;
    audio.play();
}

audio.addEventListener('ended', playNext);

playNext();

var isInSilence = function(){
    return compressor.reduction.value >= -50;
}

var tries = 0;

var checker = function() {
    tries = isInSilence() ? tries + 1 : 0;
    if(tries >= 5) playNext();
    setTimeout(checker, 1000);
}

checker();

最佳答案

这是一个可能的解决方案,使用不同的方法 - 压缩器节点。这是一个简短的描述,但应该足以让您填写用例的详细信息:

创建一个压缩器节点并将您的输入源连接到它。 然后将压缩器连接到增益节点并将增益节点静音(将其设置为零)。将增益节点连接到 audioContext.destination

获取您的输入源并将其连接到 audioContext.destination

设置压缩器属性值以检测信号(以便它触发减少值)。

compressor.reduction.value 包装在 setIntervalrequestAnimationFrame 中以检查更改。

编写此值更改(或不更改)时执行所需操作所需的逻辑。

关于javascript - 我如何使用从 audioContext 创建的分析器来检测是否可以听到播放的声音?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34937179/

相关文章:

javascript - AJAX - 带有嵌套的 promise

javascript - 在 IE 7 中替换显示 ='table-cell'

javascript - 如何使用 angularjs/javascript 获取浏览器中所有打开的网址?

html - 如何使用 CSS 反转元素位置?

javascript - 设置脚本添加的 IFRAME 的innerHTML

javascript - 在节拍器中为浏览器准确定时的声音

javascript - Reactjs - 我是否有义务将我的嵌套组件传递到 div 框中以触发函数?

javascript - 使用javascript添加样式一个词但避免链接

javascript - 从服务器 chrome 加载时,HTML5 foo.currentTime=1 不工作

php - 使用 PHP 自动检测并在 html 内容中嵌入 MP4/MP3 链接