好的,我正在Electron项目中使用Meyda(一个用于提取音频特征的库)。为了处理该项目中与音频相关的所有事情,我实现了一个Audio()
类。总而言之,我得到了音轨,将其拆分为左右声道,然后再次合并。对于每个通道,将有一个Meyda分析仪提取功能。一个简化的代码(仅显示meyda将数据发送到频谱图对象)将是:
class Audio {
constructor(audioElementID, spectrogramObj) {
const audioContext = new AudioContext();
this.audioElement = document.getElementById(audioElementID);
const track = audioContext.createMediaElementSource(this.audioElement);
const splitter = audioContext.createChannelSplitter(2);
track.connect(splitter);
this.gainNode = {
master: audioContext.createGain(),
left: audioContext.createGain(),
right: audioContext.createGain()
};
splitter.connect(this.gainNode.left, 0);
splitter.connect(this.gainNode.right, 1);
const merger = audioContext.createChannelMerger(2);
this.gainNode.left.connect(merger, 0, 0);
this.gainNode.right.connect(merger, 0, 1);
merger.connect(this.gainNode.master);
this.gainNode.master.connect(audioContext.destination);
// first analyzer
this.analyzerLeft = Meyda.createMeydaAnalyzer({
'audioContext': audioContext,
'source': this.gainNode.left,
'bufferSize': 1024,
'featureExtractors': ['amplitudeSpectrum'],
'callback': features => {
spectrogramObj.left.updatePlot(features.amplitudeSpectrum);
}
});
// second analyzer
this.analyzerRight = Meyda.createMeydaAnalyzer({
'audioContext': audioContext,
'source': this.gainNode.right,
'bufferSize': 1024,
'featureExtractors': ['amplitudeSpectrum'],
'callback': features => {
spectrogramObj.right.updatePlot(features.amplitudeSpectrum);
}
});
}
play() {
this.audioElement.play();
this.analyzerLeft.start();
this.analyzerRight.start();
};
pause() {
this.audioElement.pause();
this.analyzerLeft.stop();
this.analyzerRight.stop();
};
}
module.exports.Audio = Audio;
如您所见,我正确地将两个分析器命名为不同的名称。问题是:只有最后一个分析仪可以工作。看来实际上analyzerLeft
和analyzerRight
都在响应上一个创建的分析器。如果我添加了一个名为thirdAnalyzer
的第三个,并且在方法play()
中请勿写入this.thirdAnalyzer.start()
,则第三个将被启动,只有这样
这是库问题还是与类实现有关的问题?
答案 0 :(得分:0)
据我所知,Meyda一次只允许一个MeydaAnalyzer。当使用factory method创建MeydaAnalyzer的新实例时,它将接收Meyda对象本身作为第二个参数。 MeydaAnalyzer确实使用此对象将所有值附加到该对象。每当您创建下一个MeydaAnalyzer时,它将简单地覆盖以前的值。
我不确定这是错误还是功能。但是,既然您已经提出了问题,我们一定会尽快发现。 :-)
同时,您可以通过在创建新的MeydaAnalyzer之后直接将内部引用复制到Meyda对象来解决此问题。例如,这将确保MeydaAnalyzer的每个实例都使用不同的ScriptProcessorNode。
this.analyzerLeft = Meyda.createMeydaAnalyzer({
// ...
});
this.analyzerLeft._m = { ...this.analyzerLeft._m };
但是请记住,此黑客使用了MeydaAnalyzer类的私有类成员,该成员可能会在将来的Meyda版本中消失,也可能不会消失。