HTML5 暂停后再播放后声音变大
HTML5 Audio gets louder after pausing then playing again
我正在用 JavaScript 制作一个音频播放器,在我添加声音可视化器之前一切正常。当我暂停歌曲然后再次播放时,每次播放时声音都会变得更大声,直到失真。
我是 HTML5 音频 API 的新手,我尝试将音量设置为固定值,但不起作用。
可视化工具的代码是:
function visualizer(audio) {
let context = new AudioContext();
const gainNode = context.createGain();
gainNode.gain.value = 1; // setting it to 100%
gainNode.connect(context.destination);
let src = context.createMediaElementSource(audio);
let analyser = context.createAnalyser();
let canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let ctx = canvas.getContext("2d");
src.connect(analyser);
analyser.connect(context.destination);
analyser.fftSize = 2048;
let bufferLength = analyser.frequencyBinCount;
let dataArray = new Uint8Array(bufferLength);
let WIDTH = ctx.canvas.width;
let HEIGHT = ctx.canvas.height;
let barWidth = (WIDTH / bufferLength) * 1.5;
let barHeight;
let x = 0;
let color = randomColor();
function renderFrame() {
requestAnimationFrame(renderFrame);
x = 0;
analyser.getByteFrequencyData(dataArray);
ctx.clearRect(0, 0, WIDTH, HEIGHT);
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
ctx.fillStyle = color;
ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
musicPlay();
renderFrame();
}
并且:
function musicPlay() {
status = 'playing';
audio.play();
}
所以,我不知道我是否在音频分析器上做错了什么,我尝试创建一个全局上下文并且每次输入时都不会执行 new AudioContext();
函数,我也尝试指定一个固定的音量:
audio.volume = 1;
或如您在函数中看到的 GainNode
,但它不起作用。
我的错误在哪里,为什么声音变大了?
此致!
--- 更新 1 ---
从 URL:
加载的音频
function loadAudioElement(url) {
return new Promise(function (resolve, reject) {
let audio = new Audio();
audio.addEventListener('canplay', function () {
/* Resolve the promise, passing through the element. */
resolve(audio);
});
/* Reject the promise on an error. */
audio.addEventListener('error', reject);
audio.src = url;
});
}
我的播放器上有:
let playButtonFunction = function () {
if (playstatus === 'pause') {
loadAudioElement(audio.src).then(
visualizer(audio)
);
} else if (playstatus === 'playing') {
musicPause();
}
};
好吧,正如 Get Off My Lawn 指出的那样,我错误地添加了多个音频元素。
解决方案是在 playButtonFunction 之外使用加载歌曲的代码,并且只执行:
let playButtonFunction = function () {
if (playstatus === 'pause') {
musicPlay();
} else if (playstatus === 'playing') {
musicPause();
}
};
但是我还有一个问题,就是 next/previous 函数。在这些情况下,我需要调用 loadAudioElement
函数,因为歌曲正在改变(当您按 play/pause 时,不,这是同一首歌)但是我又遇到了同样的问题。
好吧,经过一番挖掘,我发现如果您想一直播放播放列表并可视化音乐,您必须在加载新歌曲之前释放旧上下文。不仅避免歌曲音量增加,cpu 和内存也会在 3 - 4 首歌曲后增加,浏览器将开始慢慢 运行 取决于机器。所以:
1 - 我创建了一个名为 clearContextAudio = false;
的全局变量
2 - 在我的 next/previous 函数中,我添加了以下代码:
if (closeAudioContext) { //MANDATORY RELEASE THE PREVIOUS RESOURCES TO AVOID OBJECT OVERLAPPING AND CPU-MEMORY USE
context.close();
context = new AudioContext();
}
loadAudioElement(audio.src).then(
visualizer(audio)
);
3 - 在我的 visualizer(audio)
函数上,我更改了:
let context = new AudioContext();
到
closeAudioContext = true; //MANDATORY RELEASE THE PREVIOUS RESOURCES TO AVOID OBJECT OVERLAPPING AND CPU-MEMORY USE
这个值被初始化为false,因为第一次没有播放歌曲,播放完歌曲后总是需要释放旧的资源,所以这个变量会一直设置为true。现在,你可以跳过所有你想要的歌曲,而不用担心内存和重叠问题。
希望这可以帮助其他人尝试实现同样的目标!此致!
我遇到了类似的问题,您是否尝试将音频上下文设置为全局对象?
这是我在这里找到的:
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext
建议创建一个AudioContext并重复使用,而不是每次都初始化一个新的
AudioContext 接口表示一个 audio-processing 图形,该图形由链接在一起的音频模块构建而成,每个模块由一个 AudioNode 表示。
音频上下文控制其包含的节点的创建以及音频处理或解码的执行。您需要在执行任何其他操作之前创建一个 AudioContext,因为一切都发生在上下文中。 建议创建一个 AudioContext 并重复使用它,而不是每次都初始化一个新的,并且可以同时为多个不同的音频源和管道使用一个 AudioContext。
我正在用 JavaScript 制作一个音频播放器,在我添加声音可视化器之前一切正常。当我暂停歌曲然后再次播放时,每次播放时声音都会变得更大声,直到失真。
我是 HTML5 音频 API 的新手,我尝试将音量设置为固定值,但不起作用。
可视化工具的代码是:
function visualizer(audio) {
let context = new AudioContext();
const gainNode = context.createGain();
gainNode.gain.value = 1; // setting it to 100%
gainNode.connect(context.destination);
let src = context.createMediaElementSource(audio);
let analyser = context.createAnalyser();
let canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let ctx = canvas.getContext("2d");
src.connect(analyser);
analyser.connect(context.destination);
analyser.fftSize = 2048;
let bufferLength = analyser.frequencyBinCount;
let dataArray = new Uint8Array(bufferLength);
let WIDTH = ctx.canvas.width;
let HEIGHT = ctx.canvas.height;
let barWidth = (WIDTH / bufferLength) * 1.5;
let barHeight;
let x = 0;
let color = randomColor();
function renderFrame() {
requestAnimationFrame(renderFrame);
x = 0;
analyser.getByteFrequencyData(dataArray);
ctx.clearRect(0, 0, WIDTH, HEIGHT);
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
ctx.fillStyle = color;
ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
musicPlay();
renderFrame();
}
并且:
function musicPlay() {
status = 'playing';
audio.play();
}
所以,我不知道我是否在音频分析器上做错了什么,我尝试创建一个全局上下文并且每次输入时都不会执行 new AudioContext();
函数,我也尝试指定一个固定的音量:
audio.volume = 1;
或如您在函数中看到的 GainNode
,但它不起作用。
我的错误在哪里,为什么声音变大了?
此致!
--- 更新 1 ---
从 URL:
加载的音频function loadAudioElement(url) {
return new Promise(function (resolve, reject) {
let audio = new Audio();
audio.addEventListener('canplay', function () {
/* Resolve the promise, passing through the element. */
resolve(audio);
});
/* Reject the promise on an error. */
audio.addEventListener('error', reject);
audio.src = url;
});
}
我的播放器上有:
let playButtonFunction = function () {
if (playstatus === 'pause') {
loadAudioElement(audio.src).then(
visualizer(audio)
);
} else if (playstatus === 'playing') {
musicPause();
}
};
好吧,正如 Get Off My Lawn 指出的那样,我错误地添加了多个音频元素。
解决方案是在 playButtonFunction 之外使用加载歌曲的代码,并且只执行:
let playButtonFunction = function () {
if (playstatus === 'pause') {
musicPlay();
} else if (playstatus === 'playing') {
musicPause();
}
};
但是我还有一个问题,就是 next/previous 函数。在这些情况下,我需要调用 loadAudioElement
函数,因为歌曲正在改变(当您按 play/pause 时,不,这是同一首歌)但是我又遇到了同样的问题。
好吧,经过一番挖掘,我发现如果您想一直播放播放列表并可视化音乐,您必须在加载新歌曲之前释放旧上下文。不仅避免歌曲音量增加,cpu 和内存也会在 3 - 4 首歌曲后增加,浏览器将开始慢慢 运行 取决于机器。所以:
1 - 我创建了一个名为 clearContextAudio = false;
2 - 在我的 next/previous 函数中,我添加了以下代码:
if (closeAudioContext) { //MANDATORY RELEASE THE PREVIOUS RESOURCES TO AVOID OBJECT OVERLAPPING AND CPU-MEMORY USE
context.close();
context = new AudioContext();
}
loadAudioElement(audio.src).then(
visualizer(audio)
);
3 - 在我的 visualizer(audio)
函数上,我更改了:
let context = new AudioContext();
到
closeAudioContext = true; //MANDATORY RELEASE THE PREVIOUS RESOURCES TO AVOID OBJECT OVERLAPPING AND CPU-MEMORY USE
这个值被初始化为false,因为第一次没有播放歌曲,播放完歌曲后总是需要释放旧的资源,所以这个变量会一直设置为true。现在,你可以跳过所有你想要的歌曲,而不用担心内存和重叠问题。
希望这可以帮助其他人尝试实现同样的目标!此致!
我遇到了类似的问题,您是否尝试将音频上下文设置为全局对象?
这是我在这里找到的:
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext
建议创建一个AudioContext并重复使用,而不是每次都初始化一个新的
AudioContext 接口表示一个 audio-processing 图形,该图形由链接在一起的音频模块构建而成,每个模块由一个 AudioNode 表示。
音频上下文控制其包含的节点的创建以及音频处理或解码的执行。您需要在执行任何其他操作之前创建一个 AudioContext,因为一切都发生在上下文中。 建议创建一个 AudioContext 并重复使用它,而不是每次都初始化一个新的,并且可以同时为多个不同的音频源和管道使用一个 AudioContext。