basic song access, previews, difficulties

This commit is contained in:
Juni
2023-01-09 11:10:17 -05:00
parent e8d72921e8
commit da2b89a0e8
11 changed files with 3463 additions and 3798 deletions

7162
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@
"start": "webpack-dev-server --host 0.0.0.0 --progress --colors --hot --inline --port 3000"
},
"dependencies": {
"@zip.js/zip.js": "2.4.12",
"aframe-aabb-collider-component": "^3.1.0",
"aframe-atlas-uvs-component": "^2.1.0",
"aframe-audioanalyser-component": "^5.2.1",
@@ -33,6 +34,7 @@
"babel-minify-webpack-plugin": "0.2.0",
"babel-preset-es2015": "6.24.1",
"babel-preset-stage-0": "6.24.1",
"beatsaver-api": "^2.1.4",
"body-parser": "1.18.2",
"classnames": "^2.2.5",
"css-loader": "^0.28.7",

View File

@@ -10,6 +10,6 @@ AFRAME.registerComponent('menu-selected-challenge-image', {
if (!this.data.selectedChallengeId) { return; }
el.setAttribute(
'material', 'src',
utils.getS3FileUrl(this.data.selectedChallengeId, 'image.jpg'));
this.data.selectedChallengeId);
}
});

View File

@@ -51,7 +51,7 @@ AFRAME.registerComponent('search-thumbnail-atlas', {
for (let i = 0; i < results.length; i++) {
let img = this.images[i] = this.images[i] || document.createElement('img');
img.crossOrigin = 'anonymous';
img.src = utils.getS3FileUrl(results[i].id, 'image.jpg');
img.src = results[i].imageUrl;
if (img.complete) {
this.draw(img, i);
} else {

View File

@@ -1,5 +1,12 @@
var algoliasearch = require('algoliasearch/lite');
var bindEvent = require('aframe-event-decorators').bindEvent;
var _ = require('lodash');
const BeatSaverAPI = require('beatsaver-api');
const api = new BeatSaverAPI({
AppName: 'Application Name',
Version: '1.0.0'
});
const zip = require("@zip.js/zip.js/dist/zip");
var client = algoliasearch('QULTOY3ZWU', 'be07164192471df7e97e6fa70c1d041d');
var algolia = client.initIndex('supersaber');
@@ -30,6 +37,7 @@ AFRAME.registerComponent('search', {
search: function (query) {
// Use cached for popular hits.
console.log(query);
if (!query && this.popularHits) {
this.eventDetail.results = this.popularHits;
this.eventDetail.query = '';
@@ -39,18 +47,52 @@ AFRAME.registerComponent('search', {
this.eventDetail.query = query;
this.queryObject.query = query;
algolia.search(this.queryObject, (err, content) => {
// Cache popular hits.
if (err) {
this.el.sceneEl.emit('searcherror', null, false);
console.error(err);
return;
}
api.searchMaps({q:query}).then((results)=>{
console.log(results);
Promise.all(_.map(results.docs, async (result) => {
let zipBlob = await fetch(result.versions[0].downloadURL).then(r => r.blob());
const zipFileReader = new zip.BlobReader(zipBlob);
const zipReader = new zip.ZipReader(zipFileReader);
const files = await zipReader.getEntries();
const info = _.find(files, {filename: "Info.dat"});
//const infoStream = new TransformStream();
//const infoPromise = new Response(infoStream.readable).text();
const infoBlob = await info.getData(new zip.BlobWriter());
const infoJson = JSON.parse(await infoBlob.text());
console.log(infoJson);
const songFile = _.find(files, {filename: infoJson._songFilename});
const songBlob = await songFile.getData(new zip.BlobWriter());
const songUrl = URL.createObjectURL(songBlob);
console.log(songUrl);
if (!query) { this.popularHits = content.hits; }
this.eventDetail.results = content.hits;
this.el.sceneEl.emit('searchresults', this.eventDetail);
});
return {
songName: result.metadata.songName,
songSubName: result.metadata.songAuthorName,
imageUrl: result.versions[0].coverURL,
songUrl: songUrl,
id: result.id,
data: result,
difficulties: _.map(infoJson._difficultyBeatmapSets[0]._difficultyBeatmaps, '_difficulty'),
numBeats: result.metadata.duration,
}
})).then((tmpResults) => {
this.eventDetail.results = tmpResults;
console.log(tmpResults);
this.el.sceneEl.emit('searchresults', this.eventDetail);
});
})
// algolia.search(this.queryObject, (err, content) => {
// // Cache popular hits.
// if (err) {
// this.el.sceneEl.emit('searcherror', null, false);
// console.error(err);
// return;
// }
// if (!query) { this.popularHits = content.hits; }
// this.eventDetail.results = content.hits;
// this.el.sceneEl.emit('searchresults', this.eventDetail);
// });
}
});

View File

@@ -11,7 +11,8 @@ AFRAME.registerComponent('song-preview-system', {
debug: {default: false},
isSearching: {default: false},
isSongLoading: {default: false}, // Continue to play preview song during loading.
selectedChallengeId: {type: 'string'}
selectedChallengeId: {type: 'string'},
songUrl: {type: 'string'}
},
init: function () {
@@ -91,7 +92,7 @@ AFRAME.registerComponent('song-preview-system', {
// Preload.
this.audioStore[data.selectedChallengeId].src =
utils.getS3FileUrl(data.selectedChallengeId, 'song.ogg');
data.songUrl;
// Remove from preload queue.
for (let i = 0; i < preloadQueue.length; i++) {
@@ -106,7 +107,7 @@ AFRAME.registerComponent('song-preview-system', {
* Create an audio element and queue to preload. If the queue is empty, preload it
* immediately.
*/
queuePreloadSong: function (challengeId, previewStartTime) {
queuePreloadSong: function (challengeId, previewStartTime, songUrl) {
if (this.audioStore[challengeId]) { return; }
const audio = document.createElement('audio');
@@ -114,7 +115,7 @@ AFRAME.registerComponent('song-preview-system', {
audio.dataset.previewStartTime = previewStartTime;
this.audioStore[challengeId] = audio;
let src = utils.getS3FileUrl(challengeId, 'song.ogg');
let src = songUrl;
if (this.currentLoadingId) {
// Audio currently loading, add to queue.
this.preloadQueue.push({
@@ -183,7 +184,7 @@ AFRAME.registerComponent('song-preview-system', {
// Prefetch buffer for playing.
if (audioanalyser.xhr) { audioanalyser.xhr.abort(); }
audioanalyser.fetchAudioBuffer(utils.getS3FileUrl(challengeId, 'song.ogg'));
audioanalyser.fetchAudioBuffer(data.songUrl);
},
/**
@@ -221,7 +222,7 @@ AFRAME.registerComponent('song-preview', {
}
this.el.sceneEl.components['song-preview-system'].queuePreloadSong(
this.data.challengeId, this.data.previewStartTime
this.data.challengeId, this.data.previewStartTime, this.data.songUrl
);
}
});

View File

@@ -35,7 +35,7 @@
bind__intro-song="isPlaying: menuActive && !menuSelectedChallenge.id; isSearching: isSearching"
bind__leaderboard="isVictory: isVictory; menuSelectedChallengeId: menuSelectedChallenge.id; challengeId: challenge.id"
bind__song="challengeId: challenge.id; isPlaying: isPlaying; isBeatsPreloaded: challenge.isBeatsPreloaded; isGameOver: isGameOver; isVictory: isVictory"
bind__song-preview-system="challengeId: challenge.id; isSearching: isSearching; isSongLoading: isSongLoading; selectedChallengeId: menuSelectedChallenge.id"
bind__song-preview-system="challengeId: challenge.id; isSearching: isSearching; isSongLoading: isSongLoading; selectedChallengeId: menuSelectedChallenge.id; songUrl: menuSelectedChallenge.songUrl"
animation__gameover="property: object3D.background; type: color; to: #750000; startEvents: gameover"
console-shortcuts
debug-beat-loader

View File

@@ -328,6 +328,7 @@ AFRAME.registerState({
menuchallengeselect: (state, id) => {
// Copy from challenge store populated from search results.
let challenge = challengeDataStore[id];
console.log("challenge store", challengeDataStore);
Object.assign(state.menuSelectedChallenge, challenge);
// Populate difficulty options.
@@ -340,7 +341,7 @@ AFRAME.registerState({
// Default to easiest difficulty.
state.menuSelectedChallenge.difficulty = state.menuDifficulties[0];
state.menuSelectedChallenge.image = utils.getS3FileUrl(id, 'image.jpg');
state.menuSelectedChallenge.image = challenge.imageUrl;
updateMenuSongInfo(state, challenge);
computeMenuSelectedChallengeIndex(state);

View File

@@ -15,7 +15,7 @@
<a-entity
id="leaderboardChallengeImage"
bind__menu-selected-challenge-image="selectedChallengeId: menuSelectedChallenge.id"
bind__menu-selected-challenge-image="selectedChallengeId: menuSelectedChallenge.imageUrl"
bind__visible="!isVictory"
geometry="primitive: plane; height: 0.12; width: 0.12"
material="shader: flat"

View File

@@ -198,7 +198,7 @@
position="0.8394583182784089 0 0.001">
<a-entity
id="menuSelectedChallengeImage"
bind__menu-selected-challenge-image="selectedChallengeId: menuSelectedChallenge.id"
bind__menu-selected-challenge-image="selectedChallengeId: menuSelectedChallenge.imageUrl"
geometry="primitive: plane; height: 0.4; width: 0.4"
material="shader: flat"
position="0 0.42 0"></a-entity>

View File

@@ -1,6 +1,13 @@
const BASE_URL = 'https://saber.supermedium.com';
const BeatSaverAPI = require('beatsaver-api');
const api = new BeatSaverAPI({
AppName: 'Application Name',
Version: '1.0.0'
});
function getS3FileUrl (id, name) {
return `${BASE_URL}/${id}-${name}?v=1`;
}
module.exports.getS3FileUrl = getS3FileUrl;