Почему при повторном прослушивании песни, качество звука ухудшается?
У меня есть несколько аудио, которые могу слушать с помощью аудиоплеера. Для этого есть отдельный класс Audioplayer
, в котором присутствуют 2 метода (на самом деле их больше, попытался сократить для большего понимания. Кому нужен весь код, то он находится здесь). Метод play
начинает запускать проигрывание песни или ставить ее на паузу, в нем присутствует работа с AudioContext
, а метод _setAudioBarsAnim
просто отображает анимацию на холсте.
Проблема состоит в том, что в первый раз, когда слушаешь песню, ее звучание обычное, а потом, когда ставишь ее на паузу и опять проигрываешь, то она становится громче и хуже по звучанию.
Только-только разбираюсь с этим инструментом, поэтому не сильно разбираюсь во всех его аспектах. В чем может быть проблема?
Audioplayer
class Audioplayer {
constructor() {
this.elAudio = document.createElement("audio");
this.elCanvasAnim = document.querySelector(".audio-player__anim-canvas");
this.play = false;
this.animIsActive = false;
this.audioAnalyser = null;
}
playAudio(audioSrc) {
if (audioSrc !== this.elAudio.src) {
this.elAudio.src = audioSrc;
this.play = true;
}
const promise = fetch(audioSrc)
.then((res) => res.blob())
.then(() => this.elAudio.play());
if (promise !== undefined) {
promise
.then(() => {
if (this.play) {
this.elAudio.play();
const ctx = new (window.AudioContext || window.webkitAudioContext)();
const source = ctx.createMediaElementSource(this.elAudio);
this.audioAnalyser = ctx.createAnalyser();
this.audioAnalyser.connect(ctx.destination);
source.connect(ctx.destination);
source.connect(this.audioAnalyser);
if (!this.animIsActive) {
this.animIsActive = true;
this._setAudioBarsAnim();
}
} else {
this.elAudio.pause();
}
}).catch((err) => {
throw err;
});
}
}
_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();
}
}
Скрипт для работы плеера
(function () {
let url = null;
const audioplayer = new Audioplayer();
function uploadFiles() {
const elFile = document.querySelector("#file");
elFile.addEventListener("change", (e) => {
const file = e.target.files[0];
url = window.URL.createObjectURL(file);
});
}
function setPlayAudio() {
const elBtnPlay = document.querySelector(".btn-play");
elBtnPlay.addEventListener("click", () => {
audioplayer.play = !audioplayer.play;
if (url) {
audioplayer.playAudio(url);
}
});
}
uploadFiles();
setPlayAudio();
}());
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.audio-player__anim-canvas {
width: 400px;
height: 200px;
background-color: black;
}
</style>
</head>
<body>
<label for="file">
Загрузить аудио
<input type="file" id="file">
</label>
<canvas class="audio-player__anim-canvas"></canvas>
<button class="btn-play">play/pause audio</button>
<script src="index.js"></script>
</body>
</html>