无法使用多个 Meyda 分析器:库问题或我的实现中的问题?
Mutiple Meyda analyzers not possible: library issue or problem in my implementation?
好的,我在 Electron 项目中使用 Meyda,这是一个用于提取音频特征的库。为了处理这个项目中与音频相关的一切,我实现了一个 Audio()
class。总结一下,我得到了音轨,将它分成左右声道并再次合并。对于每个通道,都会有一个 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()
DO NOT 中写 this.thirdAnalyzer.start()
,第三个将启动,即使这样,只有它。
这是库问题还是与 Class 实施相关的问题?
据我所知,Meyda 一次只允许一个 MeydaAnalyzer。当您使用 factory method 创建 MeydaAnalyzer 的新实例时,它会接收 Meyda 对象本身作为第二个参数。 MeydaAnalyzer 确实使用此对象将所有值附加到它。每当您创建下一个 MeydaAnalyzer 时,它都会简单地覆盖以前的值。
我不确定这是错误还是功能。但由于您已经提交了一个问题,我们很快就会发现。 :-)
同时,您可以通过在创建新的 MeydaAnalyzer 后直接复制对 Meyda 对象的内部引用来解决此问题。例如,这将确保 MeydaAnalyzer 的每个实例使用不同的 ScriptProcessorNode。
this.analyzerLeft = Meyda.createMeydaAnalyzer({
// ...
});
this.analyzerLeft._m = { ...this.analyzerLeft._m };
但请记住,此 hack 使用了 MeydaAnalyzer class 的私有 class 成员,它可能会或可能不会在 Meyda 的未来版本中消失。
好的,我在 Electron 项目中使用 Meyda,这是一个用于提取音频特征的库。为了处理这个项目中与音频相关的一切,我实现了一个 Audio()
class。总结一下,我得到了音轨,将它分成左右声道并再次合并。对于每个通道,都会有一个 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()
DO NOT 中写 this.thirdAnalyzer.start()
,第三个将启动,即使这样,只有它。
这是库问题还是与 Class 实施相关的问题?
据我所知,Meyda 一次只允许一个 MeydaAnalyzer。当您使用 factory method 创建 MeydaAnalyzer 的新实例时,它会接收 Meyda 对象本身作为第二个参数。 MeydaAnalyzer 确实使用此对象将所有值附加到它。每当您创建下一个 MeydaAnalyzer 时,它都会简单地覆盖以前的值。
我不确定这是错误还是功能。但由于您已经提交了一个问题,我们很快就会发现。 :-)
同时,您可以通过在创建新的 MeydaAnalyzer 后直接复制对 Meyda 对象的内部引用来解决此问题。例如,这将确保 MeydaAnalyzer 的每个实例使用不同的 ScriptProcessorNode。
this.analyzerLeft = Meyda.createMeydaAnalyzer({
// ...
});
this.analyzerLeft._m = { ...this.analyzerLeft._m };
但请记住,此 hack 使用了 MeydaAnalyzer class 的私有 class 成员,它可能会或可能不会在 Meyda 的未来版本中消失。