首页 > 解决方案 > 无法使用多个 Meyda 分析器:库问题或我的实现中的问题?

问题描述

好的,我在一个 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所有这些都在强调创建的最后一个分析器。如果我添加第三个,命名为DO NOT writethirdAnalyzer方法,即使如此,第三个也会启动,只有它。play() this.thirdAnalyzer.start()

这是库问题还是与类实现相关的问题?

标签: javascriptweb-audio-api

解决方案


据我所知,Meyda 一次只允许一个 MeydaAnalyzer。当您使用工厂方法创建 MeydaAnalyzer 的新实例时,它会接收 Meyda 对象本身作为第二个参数。MeydaAnalyzer 确实使用此对象将所有值附加到它。每当您创建下一个 MeydaAnalyzer 时,它都会简单地覆盖以前的值。

我不确定这是错误还是功能。但是由于您已经提交了问题,我们肯定会很快发现。:-)

同时,您可以通过在创建新的 MeydaAnalyzer 后直接复制对 Meyda 对象的内部引用来解决此问题。例如,这将确保 MeydaAnalyzer 的每个实例使用不同的 ScriptProcessorNode。

this.analyzerLeft = Meyda.createMeydaAnalyzer({
    // ...
});

this.analyzerLeft._m = { ...this.analyzerLeft._m };

但请记住,此 hack 使用 MeydaAnalyzer 类的私有类成员,该成员可能会或可能不会在未来版本的 Meyda 中消失。


推荐阅读