diff --git a/hitsounds/convert.sh b/hitsounds/convert.sh index 95961bb..b367cb5 100644 --- a/hitsounds/convert.sh +++ b/hitsounds/convert.sh @@ -21,5 +21,4 @@ ffmpeg -i soft-hitclap.wav soft-hitclap.ogg ffmpeg -i soft-sliderslide.wav soft-sliderslide.ogg ffmpeg -i soft-sliderwhistle.wav soft-sliderwhistle.ogg ffmpeg -i soft-slidertick.wav soft-slidertick.ogg - ffmpeg -i combobreak.ogg combobreak.mp3 \ No newline at end of file diff --git a/scripts/downloader.js b/scripts/downloader.js index 2939165..b7ace66 100644 --- a/scripts/downloader.js +++ b/scripts/downloader.js @@ -1,84 +1,182 @@ // beatmap downloader -function startpreview(box) { - let volume = 1; - if (window.gamesettings) { - volume = (window.gamesettings.mastervolume/100) * (window.gamesettings.musicvolume/100); - volume = Math.min(1, Math.max(0, volume)); - } - let audios = document.getElementsByTagName("audio"); - for (let i=0; i 9.3) // assume it's 10s long - a.volume = Math.max(0, a.volume - 0.05*volume); - if (a.volume == 0) - clearInterval(fadeOut); - }, 30); - a.softstop = function() { - let fadeOut = setInterval(function(){ - a.volume = Math.max(0, a.volume - 0.05*volume); - if (a.volume == 0) { - clearInterval(fadeOut); - a.remove(); +(() => { + + /** + * Preview Audio + */ + class PreviewAudio { + /** + * Build a PreviewAudio object + * @param {string | number} sid Beatmap's sid + * @param {number} volume Volume of preview audio + */ + constructor(sid, volume = 1) { + const audioContext = new Audio("https://cdn.sayobot.cn:25225/preview/" + sid + ".mp3"); + this._sid = sid; + this._volume = volume; + this._audioContext = audioContext; + this._playing = false; + this._ready = false; + this._fadeTimer = 0; + this._playTimer = 0; + audioContext.load(); + audioContext.volume = 0; + audioContext.addEventListener('canplay', () => { + this._ready = true + if(this._playing === true){ + this.play(); + } + }, {once: true}) + } + play() { + this._playing = true; + if(this._ready){ + this._playing = true + this._audioContext.volume = 0; + this._audioContext.currentTime = 0; + this._audioContext.play(); + clearInterval(this._fadeTimer); + clearTimeout(this._playTimer); + this._fadeTimer = setInterval(() => { + if (this._audioContext.volume < this._volume) + this._audioContext.volume = Math.min(this._volume, this._audioContext.volume + 0.05 * this._volume); + else + clearInterval(this._fadeTimer); + clearTimeout(this._playTimer); + }, 30); + this._playTimer = setTimeout(() => { + this._audioContext.volume = this._volume; + clearInterval(this._fadeTimer); + clearTimeout(this._playTimer); + }, 600); } - }, 10); + } + stop() { + this._playing = false + clearInterval(this._fadeTimer); + clearTimeout(this._playTimer); + this._fadeTimer = setInterval(() => { + this._audioContext.volume = Math.max(0, this._audioContext.volume - 0.05 * this._volume); + if (this._audioContext.volume === 0) { + this._audioContext.pause(); + clearInterval(this._fadeTimer); + clearTimeout(this._playTimer); + } + }, 10); + this._playTimer = setTimeout(() => { + this._audioContext.pause(); + clearInterval(this._fadeTimer); + clearTimeout(this._playTimer); + }, 200); + } + set volume(value) { + this._volume = value; + } + get volume() { + return this._volume; + } } -} -function startdownload(box) { - startpreview(box); - if (box.downloading) { - return; - } - let url = "https://dl.sayobot.cn/beatmaps/download/novideo/" + box.sid; - box.downloading = true; - box.classList.add("downloading"); - let xhr = new XMLHttpRequest(); - xhr.responseType = 'arraybuffer'; - xhr.open("GET", url); - // create download progress bar - let container = document.createElement("div"); - let title = document.createElement("div"); - let bar = document.createElement("progress"); - container.className = "download-progress"; - title.className = "title"; - title.innerText = box.setdata.title; - container.appendChild(title); - container.appendChild(bar); - // insert so that download list from recent to old - let statuslines = document.getElementById("statuslines"); - statuslines.insertBefore(container, statuslines.children[3]); - bar.max = 1; - bar.value = 0; - // async part - xhr.onload = function() { - box.oszblob = new Blob([xhr.response]); - bar.className = "finished"; - box.classList.remove("downloading"); + class PreviewAudioManager { + /** + * Create a preview audio manager + * @param {object} [settings] Preview audio manager settings + * @param {number} [settings.volume] Audio's volume + */ + constructor(settings = {}) { + const {volume} = settings + /** + * @type {PreviewAudio} + */ + this._active = null; + this._volume = volume; + } + /** + * Play preview audio + * @param {string | number} sid Beatmap's sid + */ + play(sid) { + if(this._active){ + this._active.stop(); + } + this._active = new PreviewAudio(sid, this._volume); + this._active.play() + } + stop() { + if(this._active){ + this._active.stop(); + } + } + set volume(value) { + if(value > 1){ + value = 1; + } + this._volume = value; + if(this._active) { + this._active.volume = value; + } + } + get volume() { + return this._volume; + } } - xhr.onprogress = function(e) { - bar.value = e.loaded / e.total; + + const previewAudioMgr = new PreviewAudioManager() + + function startpreview(box) { + let volume = 1; + if (window.gamesettings) { + volume = (window.gamesettings.mastervolume/100) * (window.gamesettings.musicvolume/100); + volume = Math.min(1, Math.max(0, volume)); + } + previewAudioMgr.volume = volume + previewAudioMgr.play(box.sid) } - xhr.onerror = function() { - console.error("download failed"); - alert("Beatmap download failed. Please retry later.") - box.downloading = false; - box.classList.remove("downloading"); + + function startdownload(box) { + startpreview(box); + if (box.downloading) { + return; + } + let url = "https://txy1.sayobot.cn/beatmaps/download/mini/" + box.sid; + box.downloading = true; + box.classList.add("downloading"); + let xhr = new XMLHttpRequest(); + xhr.responseType = 'arraybuffer'; + xhr.open("GET", url); + // create download progress bar + let container = document.createElement("div"); + let title = document.createElement("div"); + let bar = document.createElement("progress"); + container.className = "download-progress"; + title.className = "title"; + title.innerText = box.setdata.title; + container.appendChild(title); + container.appendChild(bar); + // insert so that download list from recent to old + let statuslines = document.getElementById("statuslines"); + statuslines.insertBefore(container, statuslines.children[3]); + bar.max = 1; + bar.value = 0; + // async part + xhr.onload = function() { + box.oszblob = new Blob([xhr.response]); + bar.className = "finished"; + box.classList.remove("downloading"); + } + xhr.onprogress = function(e) { + bar.value = e.loaded / e.total; + } + xhr.onerror = function() { + console.error("download failed"); + alert("Beatmap download failed. Please retry later.") + box.downloading = false; + box.classList.remove("downloading"); + } + xhr.send(); } - xhr.send(); -} \ No newline at end of file + + window.startdownload = startdownload + window.previewAudioMgr = previewAudioMgr +})() \ No newline at end of file