• Почему при повторном прослушивании песни, качество звука ухудшается?

    @alexandr-web Автор вопроса
    Программист
    Как я понял проблема была в том, что я несколько раз инициализировал AudioContext, поэтому в этот раз я сделал проверку на то, что он уже инициализирован.

    Поместил всю работу с AudioContext в отдельный метод для разделения логики.

    Сделал проверку состояния AudioContext (кому интересно, то вам сюда)

    Также добавил gainNode, который потом изменяю, если меняется громкость аудио (эта работа происходит уже в другом методе, здесь его нет, кому интересно, то вам сюда)

    Метод _setAudioBarsAnim не изменял.

    В конечном итоге получилось это:

    class Audioplayer {
        constructor() {
            this.elAudio = document.createElement("audio");
            this.elCanvasAnim = document.querySelector(".audio-player__anim-canvas");
    
            this.play = false;
            this.animIsActive = false;
            this.audioContext = null;
            this.gainNode = null;
            this.audioAnalyser = null;
        }
    
        playAudio(audioSrc) {
            if (audioSrc !== this.elAudio.src) {
                this.elAudio.src = audioSrc;
                this.play = true;
            }
    
            const promise = this.elAudio.play();
    
            if (promise instanceof Promise) {
                promise
                    .then(() => {
                        if (this.audioContext instanceof AudioContext && this.audioContext.state === "suspended") {
                            this.audioContext.resume();
                        }
    
                        if (this.play) {
                            this.elAudio.play();
    
                            this._initAudioContext();
    
                            if (!this.animIsActive) {
                                this.animIsActive = true;
    
                                this._setAudioBarsAnim();
                            }
                        } else {
                            this.elAudio.pause();
                        }
                    }).catch((err) => {
                        throw err;
                    });
            }
        }
    
        _initAudioContext() {
            if (this.audioContext) {
                return;
            }
    
            this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
            this.gainNode = this.audioContext.createGain();
            this.audioAnalyser = this.audioContext.createAnalyser();
    
            const source = this.audioContext.createMediaElementSource(this.elAudio);
    
            this.audioAnalyser.fftSize = 2048;
    
            source
                .connect(this.gainNode)
                .connect(this.audioAnalyser)
                .connect(this.audioContext.destination);
        }
    
        _setAudioBarsAnim() {
            const canvas = this.elCanvasAnim;
            const ctx = canvas.getContext("2d");
            const countLinesOnArea = 250;
            const widthLine = canvas.offsetWidth / countLinesOnArea;
    
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
    
            const drawBars = () => {
                const fbcArray = new Uint8Array(this.audioAnalyser.frequencyBinCount);
    
                this.audioAnalyser.getByteFrequencyData(fbcArray);
    
                ctx.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight);
    
                fbcArray.slice(0, countLinesOnArea).forEach((n, i) => {
                    const x = i * widthLine;
                    const percent = Math.ceil((n / 255) * 100);
                    const height = (percent * canvas.offsetHeight) / 100;
    
                    ctx.fillStyle = "white";
                    ctx.fillRect(x, canvas.offsetHeight - height, widthLine, height);
                });
    
                (window.requestAnimationFrame || window.webkitRequestAnimationFrame)(drawBars);
            };
    
            drawBars();
        }
    }
    Ответ написан
    Комментировать