AudioContext实现同时播放两首音乐在左右音道上
直接上代码
<!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>AudioContext实现同时播放两首音乐在左右音道上</title>
</head>
<style></style>
<body>
<canvas class="canvas" id="canvas" width="400" height="400"></canvas>
<button id="stop">暂停</button>
<button id="cont">继续</button>
<button id="start">开始</button>
<div class="setAudioVol">
<table border="1">
<tr>
<th></th>
<th>左声道</th>
<th>右声道</th>
</tr>
<tr>
<td>A1</td>
<td>
<input
type="checkbox"
name="l"
id="lVolCheckBox"
checked="checked"
/>
</td>
<td>
<input
type="checkbox"
name="r"
id="rVolCheckBox"
checked="checked"
/>
</td>
</tr>
</table>
</div>
L<input type="range" min="0" max="200" value="100" id="equalizer" />R
</body>
<script>
window.onload = function () {
const canvas = document.getElementById("canvas");
var context = new AudioContext(); // 创建Audio上下文
var mergerleft = context.createChannelMerger(2); // 创建 左合成器
var mergerright = context.createChannelMerger(2); // 创建 右合成器
var AllMerget = context.createChannelMerger(2); //创建 合成器合成左右合成器
var lsource = null;
var rsource = null;
var con = 0;
var audioBuffer = null;
var lGain = context.createGain(), // 左声道
rGain = context.createGain(), // 右声道
vol = 100, // 音量
lVol = 100, // 左声道
rVol = 100; // 右声道
lGain.gain.value = 1; //设置左声道声音为1
rGain.gain.value = 1;
document
.getElementById("lVolCheckBox")
.addEventListener("change", function (e) {
console.log(e);
if (e.target.checked) {
lVol = 100;
} else {
lVol = 0;
}
setVolume();
});
document
.getElementById("rVolCheckBox")
.addEventListener("change", function (e) {
console.log(e);
if (e.target.checked) {
rVol = 100;
} else {
rVol = 0;
}
setVolume();
});
// 声道控制
document
.getElementById("equalizer")
.addEventListener("change", function () {
lVol = equalizer.value > 100 ? 100 : equalizer.value;
rVol = equalizer.value < 100 ? 100 : 200 - equalizer.value;
setVolume();
});
// 设置音量
function setVolume() {
lGain.gain.value = ((lVol / 100) * vol) / 100;
rGain.gain.value = ((rVol / 100) * vol) / 100;
context.resume();
}
function loadAudioFile(url) {
return new Promise((res, rej) => {
var xhr = new XMLHttpRequest(); //通过XHR下载音频文件
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function (e) {
//下载完成
res(this.response);
};
xhr.send();
});
}
Promise.all([
loadAudioFile(
"https://djdemo.bjbtf.cn:36110//2016/House/20140825/[House]128bpm_Shameless_Whoomp_Yeahhh_It_Is_[Original_Vs_Booty_Mix]_.mp3"
),
loadAudioFile(
"https://djdemo.bjbtf.cn:36110//2016/CLUB%E5%95%86%E4%B8%9A/club%E5%A4%96%E6%96%87/20150519/Bpm128_Desireless_Voyage_Voyage_[FuzzDead_Reboot].mp3"
),
]).then(
(res) => {
Promise.all([
context.decodeAudioData(res[0]),
context.decodeAudioData(res[1]),
]).then((audioData) => {
//赋值->拆分->合成->输出
lsource = context.createBufferSource();
rsource = context.createBufferSource();
lsource.buffer = audioData[0];
rsource.buffer = audioData[1];
let lsplitterNode = context.createChannelSplitter(2);
let rsplitterNode = context.createChannelSplitter(2);
lsource.connect(lsplitterNode);
rsource.connect(rsplitterNode);
lsplitterNode.connect(lGain, 0);
rsplitterNode.connect(rGain, 1);
lGain.connect(mergerleft, 0, 0);
rGain.connect(mergerright, 0, 1);
mergerleft.connect(AllMerget, 0, 0);
mergerright.connect(AllMerget, 0, 1);
AllMerget.connect(context.destination);
});
},
(err) => {}
);
document.getElementById("stop").addEventListener("click", function () {
context.suspend();
});
document.getElementById("cont").addEventListener("click", function () {
context.resume();
});
document.getElementById("start").addEventListener("click", function () {
lsource.start(0); //立即播放
rsource.start(0); //立即播放
});
};
</script>
</html>