// 加载语言
let zh_CN = ($("title").text() == "音频可视化圆环特效");
// 初始化文件
function clearInputFiles(inputId) {
let inputElement = document.getElementById(inputId);
if (inputElement.files && inputElement.files.length > 0) {
let reader = new FileReader();
reader.readAsArrayBuffer(inputElement.files[0]);
reader.onload = function () {
inputElement.value = '';
};
}
}
// 还原背景图
function recover_bg() {
$(".bg").css("background-image", "url(./src/bg.jpg)");
clearInputFiles("bgFile");
}
// 加载全屏按钮
function openFullscreen(elem) {
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) { // Firefox
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) { // Chrome, Safari and Opera
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) { // IE/Edge
elem.msRequestFullscreen();
}
}
// exit fullscreen
function closeFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) { // Firefox
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) { // Chrome, Safari and Opera
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) { // IE/Edge
document.msExitFullscreen();
}
}
function loadFullscreen() {
// fullscreen related
document.getElementById("fullscreen").addEventListener("click", function () {
if (document.fullscreenElement) {
closeFullscreen();
} else {
openFullscreen(document.documentElement);
}
});
document.addEventListener('fullscreenchange', function () {
if (document.fullscreenElement) {
document.getElementById("fullscreen").innerText = zh_CN ? "退出全屏" : "Exit fullscreen";
} else {
document.getElementById("fullscreen").innerText = zh_CN ? "全屏" : "Fullscreen";
}
});
}
// 检查设备类型
function checkDeviceType() {
const userAgent = navigator.userAgent || window.opera;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)) {
let warning = zh_CN ? "请使用 PC 端浏览器查看!" : "Please view on PC browsers!"
$("body").remove();
$("html").append(`
${warning}
`);
return false;
}
return true;
}
window.onload = function () {
if (!checkDeviceType()) return;
wrap.width = window.innerWidth - 1;
wrap.height = window.innerHeight - 1;
let canvasCtx = wrap.getContext("2d");
let AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
let audioContext = new AudioContext();
canvasCtx.shadowColor = "white";
canvasCtx.shadowBlur = 10;
$("#home").click(function () {
recover_bg();
});
$('#upl').hover(function () {
$(this).removeClass("first");
});
$('#bgFile').change(function () {
if (this.files.length <= 0) return;
if (this.files[0].size > 5242880) {
alert(zh_CN ? '文件大小超过 5M' : 'File size larger than 5M');
return;
}
let file = this.files[0];
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
$('.bg').css('background-image', 'url(' + reader.result + ')');
};
});
$('#musicFile').change(function () {
if (this.files.length == 0) {
$("#tip").text(zh_CN ? "上传待可视化的音频👉" : "Upload audio to be visualized👉");
return;
}
audioContext.close();
audioContext = new AudioContext();
$("#startStop").val(zh_CN ? '暂停' : 'Pause');
let file = $('#musicFile')[0].files[0];
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = function (e) {
let count = 0;
$('#tip').text(zh_CN ? '开始解码' : 'Start decoding')
let timer = setInterval(function () {
count++;
$('#tip').text((zh_CN ? '正在解码中, 已耗时 ' : 'In decoding, already used ') + count + 's')
}, 1000)
audioContext.decodeAudioData(e.target.result, function (buffer) {
clearInterval(timer)
$('#tip').text((zh_CN ? '解码成功, 总耗时 ' : 'Decoded successfully, total time ') + count + 's');
let audioBufferSourceNode = audioContext.createBufferSource();
let analyser = audioContext.createAnalyser();
audioBufferSourceNode.connect(analyser);
analyser.connect(audioContext.destination);
audioBufferSourceNode.buffer = buffer;
audioBufferSourceNode.start();
startStop.onclick = function () {
if (audioContext.state === 'running') {
audioContext.suspend().then(function () {
$("#startStop").val(zh_CN ? '播放' : 'Play');
});
} else if (audioContext.state === 'suspended') {
audioContext.resume().then(function () {
$("#startStop").val(zh_CN ? '暂停' : 'Pause');
});
}
}
let oW = wrap.width;
let oH = wrap.height;
let color1 = canvasCtx.createLinearGradient(oW / 2, oH / 2 - 10, oW / 2, oH / 2 - 150);
color1.addColorStop(0, '#1E90FF');
color1.addColorStop(.25, '#FF7F50');
color1.addColorStop(.5, '#8A2BE2');
color1.addColorStop(.75, '#4169E1');
color1.addColorStop(1, '#00FFFF');
let color2 = canvasCtx.createLinearGradient(0, 0, oW, oH);
color2.addColorStop(0, '#1E90FF');
color2.addColorStop(.25, '#FFD700');
color2.addColorStop(.5, '#8A2BE2');
color2.addColorStop(.75, '#4169E1');
color2.addColorStop(1, '#FF0000');
let output = new Uint8Array(180);
let du = 2;
let R = 200;
let W = 2;
(function drawSpectrum() {
analyser.getByteFrequencyData(output);
canvasCtx.clearRect(0, 0, wrap.width, wrap.height);
for (let i = 0; i < 360; i++) {
let value = output[i] / 10;
canvasCtx.beginPath();
canvasCtx.lineWidth = W;
Rv1 = (R - value);
Rv2 = (R + value);
canvasCtx.moveTo((Math.sin((i * du) / 180 * Math.PI) * Rv1 + oW / 2), -Math.cos((i * du) / 180 * Math.PI) * Rv1 + oH / 2);
canvasCtx.lineTo((Math.sin((i * du) / 180 * Math.PI) * Rv2 + oW / 2), -Math.cos((i * du) / 180 * Math.PI) * Rv2 + oH / 2);
canvasCtx.strokeStyle = color1;
canvasCtx.stroke();
}
canvasCtx.font = "italic bold 20px Microsoft Yahei";
canvasCtx.fillStyle = color2;
canvasCtx.textAlign = "center";
canvasCtx.textBaseline = "middle";
canvasCtx.fillText(file.name.split('.mp3')[0], oW / 2, oH / 2);
requestAnimationFrame(drawSpectrum);
})();
$(window).resize(function () {
wrap.width = window.innerWidth - 1;
wrap.height = window.innerHeight - 1;
let oW = wrap.width;
let oH = wrap.height;
(function drawSpectrum() {
analyser.getByteFrequencyData(output);
canvasCtx.clearRect(0, 0, wrap.width, wrap.height);
for (let i = 0; i < 360; i++) {
let value = output[i] / 10;
canvasCtx.beginPath();
canvasCtx.lineWidth = W;
Rv1 = (R - value);
Rv2 = (R + value);
canvasCtx.moveTo((Math.sin((i * du) / 180 * Math.PI) * Rv1 + oW / 2), -Math.cos((i * du) / 180 * Math.PI) * Rv1 + oH / 2);
canvasCtx.lineTo((Math.sin((i * du) / 180 * Math.PI) * Rv2 + oW / 2), -Math.cos((i * du) / 180 * Math.PI) * Rv2 + oH / 2);
canvasCtx.strokeStyle = color1;
canvasCtx.stroke();
}
canvasCtx.font = "italic bold 20px Microsoft Yahei";
canvasCtx.fillStyle = color2;
canvasCtx.textAlign = "center";
canvasCtx.textBaseline = "middle";
canvasCtx.fillText(file.name.split('.mp3')[0], oW / 2, oH / 2);
requestAnimationFrame(drawSpectrum);
})();
});
})
}
});
loadFullscreen();
}