Многочисленные анализаторы Meyda невозможны: проблема с библиотекой или проблема в моей реализации? - PullRequest
0 голосов
/ 08 мая 2019

Хорошо, я использую Meyda, библиотеку для извлечения аудио функций, в проекте Electron. Для обработки всего, что связано со звуком в этом проекте, я реализовал класс Audio(). Подводя итог, я получаю звуковую дорожку, разделяю ее на левый и правый каналы и снова объединяю. Для каждого канала будет реализован анализатор 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(), третий будет запущен, и только он.

Это проблема с библиотекой или что-то, связанное с реализацией класса?

1 Ответ

0 голосов
/ 08 мая 2019

Из того, что я могу сказать, похоже, что Meyda позволяет только один MeydaAnalyzer одновременно. Когда вы создаете новый экземпляр MeydaAnalyzer с фабричным методом , он получает сам объект Meyda в качестве второго параметра. MeydaAnalyzer использует этот объект, чтобы присоединить к нему все значения. Каждый раз, когда вы создаете следующий MeydaAnalyzer, он просто перезаписывает предыдущие значения.

Я не уверен, что это ошибка или особенность. Но так как вы уже подали вопрос, мы обязательно узнаем в ближайшее время. : -)

Тем временем вы можете обойти эту проблему, скопировав внутреннюю ссылку на объект Meyda непосредственно после создания нового MeydaAnalyzer. Это, например, позволит убедиться, что каждый экземпляр MeydaAnalyzer использует свой ScriptProcessorNode.

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

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

Но имейте в виду, что в этом хаке используется член частного класса класса MeydaAnalyzer, который может исчезнуть или не исчезнуть в будущей версии Meyda.

...