Javascript - Web Audio API -- Range type Input 在 Firefox 中不是动态的,但在 Chrome 中是动态的 -added reprex
Javascript - Web Audio API -- Range type Input is not dynamic in Firefox, but it is dynamic in Chrome -added reprex
- 增益控制器在 chrome 上动态工作,但在 firefox 中则不然。我需要为浏览器重新播放音频文件以识别 firefox 范围输入的新输入值。我不知道为什么。
- 顺便把一个mp3文件放到"example.mp3"部分。
- 我是新来的。尝试了代表。对不起,如果它不是应该的
[HTML + Javascript]
<!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>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div>
<button class="button">click</button>
<input
class="input"
type="range"
step="0.01"
min="0"
max="1.20"
value="0.60"
/>
</div>
</body>
<script src="script.js" type="text/javascript"></script>
</html>
<script type="text/javascript">
loopify("example.mp3", function (err, loop) {
// If something went wrong, `err` is supplied
document.querySelector(".button").dataset.playing = "false";
if (err) {
return console.err(err);
}
document.querySelector(".button").addEventListener("click", function () {
if (this.dataset.playing === "false") {
loop.play();
this.dataset.playing = "true";
} else if (this.dataset.playing === "true") {
setTimeout(loop.stop, 250);
this.dataset.playing = "false";
}
});
});
</script>
[Javascript]
(function () {
function loopify(uri, cb) {
var context = new (window.AudioContext || window.webkitAudioContext)(),
request = new XMLHttpRequest();
const gainNode = context.createGain();
request.responseType = "arraybuffer";
request.open("GET", uri, true);
// XHR failed
request.onerror = function () {
cb(new Error("Couldn't load audio from " + uri));
};
// XHR complete
request.onload = function () {
context.decodeAudioData(request.response, success, function (err) {
// Audio was bad
cb(new Error("Couldn't decode audio from " + uri));
});
};
request.send();
function success(buffer) {
var source;
// fade-out
document.querySelector(".button").onclick = function () {
if (this.dataset.playing === "true") {
gainNode.gain.setTargetAtTime(0, context.currentTime, 0.25);
}
};
function play() {
// Stop if it's already playing
stop();
// Create a new source (can't replay an existing source)
source = context.createBufferSource();
source.connect(gainNode).connect(context.destination);
// fade-in
gainNode.gain.value = 0.1;
gainNode.gain.setTargetAtTime(
document.querySelector(".input").value,
context.currentTime,
0.25
);
//gain input assignment
document.querySelector(".input").addEventListener(
"input",
function () {
gainNode.gain.value = this.value;
},
false
);
// Set the buffer
source.buffer = buffer;
source.loop = true;
// Play it
source.start(0);
}
function stop() {
// Stop and clear if it's playing
if (source) {
source.stop();
source = null;
}
}
cb(null, {
play: play,
stop: stop,
});
}
}
loopify.version = "0.1";
if (typeof define === "function" && define.amd) {
define(function () {
return loopify;
});
} else if (typeof module === "object" && module.exports) {
module.exports = loopify;
} else {
this.loopify = loopify;
}
})();
[CSS]
div {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
经过一些实验并尝试重现您的代码后,我偶然发现了一些奇怪的东西。
每当我们使用 gainNode.gain.setTargetAtTime
时,我们都无法使用 setter gainNode.gain.value
更新增益值。我在 setTargetAtTime
or value
的文档中找不到关于为什么会发生这种情况的任何解释。
幸运的是,有一个修复程序没有 破坏 setTargetAtTime
提供的 fade-in。
解决方案在于使用 setValueAtTime
而不是 setter.
设置增益值
const input = document.querySelector(".input");
gainNode.gain.value = 0.1;
gainNode.gain.setTargetAtTime(
input.value,
context.currentTime,
0.25
);
input.addEventListener(
"input",
function () {
gainNode.gain.setValueAtTime(
this.value,
context.currentTime
)
},
false
);
- 增益控制器在 chrome 上动态工作,但在 firefox 中则不然。我需要为浏览器重新播放音频文件以识别 firefox 范围输入的新输入值。我不知道为什么。
- 顺便把一个mp3文件放到"example.mp3"部分。
- 我是新来的。尝试了代表。对不起,如果它不是应该的
[HTML + Javascript]
<!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>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div>
<button class="button">click</button>
<input
class="input"
type="range"
step="0.01"
min="0"
max="1.20"
value="0.60"
/>
</div>
</body>
<script src="script.js" type="text/javascript"></script>
</html>
<script type="text/javascript">
loopify("example.mp3", function (err, loop) {
// If something went wrong, `err` is supplied
document.querySelector(".button").dataset.playing = "false";
if (err) {
return console.err(err);
}
document.querySelector(".button").addEventListener("click", function () {
if (this.dataset.playing === "false") {
loop.play();
this.dataset.playing = "true";
} else if (this.dataset.playing === "true") {
setTimeout(loop.stop, 250);
this.dataset.playing = "false";
}
});
});
</script>
[Javascript]
(function () {
function loopify(uri, cb) {
var context = new (window.AudioContext || window.webkitAudioContext)(),
request = new XMLHttpRequest();
const gainNode = context.createGain();
request.responseType = "arraybuffer";
request.open("GET", uri, true);
// XHR failed
request.onerror = function () {
cb(new Error("Couldn't load audio from " + uri));
};
// XHR complete
request.onload = function () {
context.decodeAudioData(request.response, success, function (err) {
// Audio was bad
cb(new Error("Couldn't decode audio from " + uri));
});
};
request.send();
function success(buffer) {
var source;
// fade-out
document.querySelector(".button").onclick = function () {
if (this.dataset.playing === "true") {
gainNode.gain.setTargetAtTime(0, context.currentTime, 0.25);
}
};
function play() {
// Stop if it's already playing
stop();
// Create a new source (can't replay an existing source)
source = context.createBufferSource();
source.connect(gainNode).connect(context.destination);
// fade-in
gainNode.gain.value = 0.1;
gainNode.gain.setTargetAtTime(
document.querySelector(".input").value,
context.currentTime,
0.25
);
//gain input assignment
document.querySelector(".input").addEventListener(
"input",
function () {
gainNode.gain.value = this.value;
},
false
);
// Set the buffer
source.buffer = buffer;
source.loop = true;
// Play it
source.start(0);
}
function stop() {
// Stop and clear if it's playing
if (source) {
source.stop();
source = null;
}
}
cb(null, {
play: play,
stop: stop,
});
}
}
loopify.version = "0.1";
if (typeof define === "function" && define.amd) {
define(function () {
return loopify;
});
} else if (typeof module === "object" && module.exports) {
module.exports = loopify;
} else {
this.loopify = loopify;
}
})();
[CSS]
div {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
经过一些实验并尝试重现您的代码后,我偶然发现了一些奇怪的东西。
每当我们使用 gainNode.gain.setTargetAtTime
时,我们都无法使用 setter gainNode.gain.value
更新增益值。我在 setTargetAtTime
or value
的文档中找不到关于为什么会发生这种情况的任何解释。
幸运的是,有一个修复程序没有 破坏 setTargetAtTime
提供的 fade-in。
解决方案在于使用 setValueAtTime
而不是 setter.
const input = document.querySelector(".input");
gainNode.gain.value = 0.1;
gainNode.gain.setTargetAtTime(
input.value,
context.currentTime,
0.25
);
input.addEventListener(
"input",
function () {
gainNode.gain.setValueAtTime(
this.value,
context.currentTime
)
},
false
);