-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
231 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<configuration> | ||
<runtime> | ||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | ||
<dependentAssembly> | ||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> | ||
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" /> | ||
</dependentAssembly> | ||
</assemblyBinding> | ||
</runtime> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>Visualizer</title> | ||
<style> | ||
#thefile { | ||
position: fixed; | ||
top: 10px; | ||
left: 10px; | ||
z-index: 100; | ||
} | ||
|
||
#canvas { | ||
position: fixed; | ||
left: 0; | ||
top: 0; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
|
||
audio { | ||
position: fixed; | ||
left: 10px; | ||
bottom: 10px; | ||
width: calc(100% - 20px); | ||
} | ||
</style> | ||
|
||
<script src="js/ODDR.js"></script> | ||
<script src="js/ORTDP.js"></script> | ||
<script> | ||
(async function () { | ||
const MAX_HEIGTH = window.innerHeight - 20; | ||
let context = new AudioContext(); | ||
let play = false; | ||
|
||
let _url = new URL(window.location.href); | ||
let has_sound = _url.searchParams.get('sound') || "false"; | ||
let host = _url.searchParams.get('host') || "localhost"; | ||
let port = _url.searchParams.get('port') || "10800"; | ||
let lineWidth = Number.parseInt(_url.searchParams.get('lineWidth') || "5"); | ||
|
||
let current_audio_buffer = null; | ||
let src = context.createBufferSource(); | ||
let analyser = context.createAnalyser(); | ||
analyser.smoothingTimeConstant = 0.75; | ||
src.connect(analyser); | ||
|
||
let oddr = new ODDR(host,port); | ||
let ortdp = new ORTDP(oddr); | ||
|
||
//链接音频输出设备 | ||
if (has_sound === "true") | ||
analyser.connect(context.destination); | ||
|
||
let last_mods = { timeRate: 1.0 }; | ||
let last_mp3 = ""; | ||
let audio_url = null; | ||
let timer = 0; | ||
|
||
//play and seek andio | ||
function restart_audio(buf, time, timeRate) { | ||
if (buf === null) return; | ||
if (time < 0) return; | ||
src.disconnect(analyser); | ||
|
||
src = context.createBufferSource(); | ||
src.buffer = buf; | ||
src.playbackRate.value = timeRate; | ||
src.connect(analyser); | ||
|
||
src.start(0, time); | ||
timer = time; | ||
play = true; | ||
} | ||
|
||
//play timer | ||
setInterval(function () { | ||
if (play === true) | ||
timer += 0.026 * last_mods.timeRate; | ||
}, Math.round(26 * last_mods.timeRate)); | ||
|
||
//http get loop | ||
async function get_loop() { | ||
let time = (await ortdp.getPlayingTime()).time / 1000.0; | ||
let beatmap = await ortdp.getBeatmapInfo(); | ||
let mods = await ortdp.getPlayingModsAt(0); | ||
|
||
let folder = beatmap.folder; | ||
let mp3 = beatmap.audioFilename; | ||
mp3 = folder + '\\' + mp3; | ||
|
||
if (folder !== "" && mp3 !== "") { | ||
if (last_mp3 != mp3) { | ||
if (play === true) { | ||
src.stop(0); | ||
play = false; | ||
} | ||
|
||
let audio_data = await ortdp.getBeatmapAudio("arraybuffer"); | ||
let buf = await context.decodeAudioData(audio_data); | ||
current_audio_buffer = buf; | ||
restart_audio(buf, time, 1.0); | ||
} | ||
} | ||
if (Math.abs(timer - time) > 0.2) | ||
restart_audio(current_audio_buffer, time+0.1, mods.timeRate); | ||
|
||
if (last_mods.timeRate != mods.timeRate) | ||
restart_audio(current_audio_buffer, time, mods.timeRate); | ||
|
||
last_mp3 = mp3; | ||
last_mods = mods; | ||
setTimeout(get_loop, 100); | ||
} | ||
|
||
//canvas initialize | ||
async function play_audio() { | ||
var canvas = document.getElementById("canvas"); | ||
canvas.width = window.innerWidth; | ||
canvas.height = window.innerHeight; | ||
var ctx = canvas.getContext("2d"); | ||
|
||
analyser.fftSize = 16384; | ||
const SKIP = 64; | ||
var bufferLength = analyser.fftSize; | ||
console.log(bufferLength); | ||
|
||
|
||
var dataArray = new Uint8Array(bufferLength); | ||
|
||
var WIDTH = canvas.width; | ||
var HEIGHT = canvas.height; | ||
var STEP = WIDTH / bufferLength; | ||
|
||
var barHeight; | ||
|
||
//render | ||
function renderFrame() { | ||
let x = 0; | ||
|
||
analyser.getByteTimeDomainData(dataArray); | ||
|
||
ctx.fillStyle = "#000"; | ||
ctx.fillRect(0, 0, WIDTH, HEIGHT); | ||
ctx.lineWidth = lineWidth; | ||
|
||
ctx.strokeStyle = "#33aacc"; | ||
ctx.beginPath(); | ||
ctx.moveTo(0,dataArray[0] / 255.0 * MAX_HEIGTH); | ||
x += STEP; | ||
|
||
for (let i = 1; i < bufferLength; i+=SKIP) { | ||
let val1 = 0; | ||
let val2 = 0; | ||
|
||
for(let j=0;j<SKIP/2;j++){ | ||
val1 += dataArray[i+j] / 255.0; | ||
} | ||
for(let j=0;j<SKIP/2;j++){ | ||
val2 += dataArray[i + SKIP/2 +j] / 255.0; | ||
} | ||
val1 /= (SKIP/2); | ||
val2 /= (SKIP/2); | ||
|
||
let r = 128 + Math.round((128 * (i / bufferLength))); | ||
let g = Math.round(val1 * val2 * 230 - (25 * (i / bufferLength))); | ||
let b = 203; | ||
|
||
ctx.lineTo(x + STEP, val2 * MAX_HEIGTH); | ||
|
||
x += STEP * SKIP; | ||
} | ||
ctx.stroke(); | ||
|
||
requestAnimationFrame(renderFrame); | ||
} | ||
renderFrame(); | ||
}; | ||
|
||
window.onload = function () { | ||
get_loop(); | ||
play_audio(); | ||
} | ||
})(); | ||
</script> | ||
</head> | ||
|
||
<body> | ||
<div id="content"> | ||
<canvas id="canvas"></canvas> | ||
</div> | ||
</body> | ||
</html> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters