Skip to content

Commit 24bf31d

Browse files
committed
Checkpoint from VS Code for coding agent session
1 parent ac2f541 commit 24bf31d

3 files changed

Lines changed: 82 additions & 208 deletions

File tree

index.html

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -97,47 +97,25 @@ <h3>🎵 Audio Tracks</h3>
9797
const AUDIO_MIME_TYPE = 'audio/mpeg';
9898

9999
// Initialize when DOM is loaded
100-
document.addEventListener('DOMContentLoaded', async function () {
100+
document.addEventListener('DOMContentLoaded', function () {
101101
// Get references to audio elements
102102
song1 = document.getElementById('song1');
103103
song2 = document.getElementById('song2');
104104

105-
// Initialize lyrics engine
105+
// Initialize lyrics engine (data is now hardcoded, so this always succeeds)
106106
lyricsEngine = new LyricsEngine();
107107

108-
// Load lyrics data first
109-
const dataLoaded = await lyricsEngine.loadLyricsData();
110-
if (!dataLoaded) {
111-
console.warn('Failed to load lyrics data, using fallback');
112-
// Set emergency fallback sources
113-
song1.src = 'song1.mp3';
114-
song2.src = 'song2.mp3';
115-
console.log('Using emergency fallback audio sources');
116-
// Show error message in sentence display
117-
document.getElementById('sentenceDisplay').innerHTML = '⚠️ Failed to load lyrics data. Please refresh the page.';
118-
} else {
119-
// Set audio sources dynamically from loaded data
120-
if (lyricsEngine.lyricsData.song_1_source) {
121-
song1.src = lyricsEngine.lyricsData.song_1_source;
122-
song1.type = AUDIO_MIME_TYPE;
123-
console.log(`Song 1 source set to: ${song1.src} (${AUDIO_MIME_TYPE})`);
124-
} else {
125-
console.error('No song_1_source found in lyrics data');
126-
}
127-
128-
if (lyricsEngine.lyricsData.song_2_source) {
129-
song2.src = lyricsEngine.lyricsData.song_2_source;
130-
song2.type = AUDIO_MIME_TYPE;
131-
console.log(`Song 2 source set to: ${song2.src} (${AUDIO_MIME_TYPE})`);
132-
} else {
133-
console.error('No song_2_source found in lyrics data');
134-
}
135-
136-
// Verify audio sources are accessible
137-
const audioReady = await lyricsEngine.verifyAudioSources();
138-
if (!audioReady) {
139-
console.warn('Some audio files may not be accessible - karaoke may not work properly');
140-
}
108+
// Set audio sources directly from lyrics data (no loading needed)
109+
if (lyricsEngine.lyricsData.song_1_source) {
110+
song1.src = lyricsEngine.lyricsData.song_1_source;
111+
song1.type = AUDIO_MIME_TYPE;
112+
console.log(`Song 1 source set to: ${song1.src} (${AUDIO_MIME_TYPE})`);
113+
}
114+
115+
if (lyricsEngine.lyricsData.song_2_source) {
116+
song2.src = lyricsEngine.lyricsData.song_2_source;
117+
song2.type = AUDIO_MIME_TYPE;
118+
console.log(`Song 2 source set to: ${song2.src} (${AUDIO_MIME_TYPE})`);
141119
}
142120

143121
// Initialize with DOM elements after data is loaded

lyrics-data.json

Lines changed: 0 additions & 64 deletions
This file was deleted.

lyrics-engine.js

Lines changed: 69 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,72 @@
55

66
class LyricsEngine {
77
constructor() {
8-
// Lyrics data - will be loaded from JSON file
9-
this.lyricsData = null;
10-
this.isDataLoaded = false;
8+
// Lyrics data - now hardcoded to prevent loading failures
9+
this.lyricsData = {
10+
offset: 17,
11+
outro: 3,
12+
song_1_source: "song1.mp3",
13+
song_2_source: "song2.mp3",
14+
sentences: [
15+
{
16+
words: [
17+
{ text: "Twinkle", duration: 1.4, recognise: false },
18+
{ text: "twinkle", duration: 1.4, recognise: false },
19+
{ text: "little", duration: 1.3, recognise: true },
20+
{ text: "star", duration: 2.0, recognise: false }
21+
]
22+
},
23+
{
24+
words: [
25+
{ text: "How", duration: 0.49, recognise: true },
26+
{ text: "I", duration: 0.46, recognise: true },
27+
{ text: "wonder", duration: 1.32, recognise: true },
28+
{ text: "what", duration: 0.69, recognise: true },
29+
{ text: "you", duration: 0.46, recognise: true },
30+
{ text: "are", duration: 1.5, recognise: true }
31+
]
32+
},
33+
{
34+
words: [
35+
{ text: "", duration: 0.5, recognise: false },
36+
{ text: "Up", duration: 0.75, recognise: true },
37+
{ text: "above", duration: 1.2, recognise: true },
38+
{ text: "the", duration: 0.6, recognise: true },
39+
{ text: "world", duration: 0.6, recognise: true },
40+
{ text: "so", duration: 0.7, recognise: true },
41+
{ text: "high", duration: 1.8, recognise: false }
42+
]
43+
},
44+
{
45+
words: [
46+
{ text: "Like", duration: 0.6, recognise: true },
47+
{ text: "a", duration: 0.7, recognise: false },
48+
{ text: "diamond", duration: 1.3, recognise: true },
49+
{ text: "in", duration: 0.4, recognise: true },
50+
{ text: "the", duration: 0.8, recognise: true },
51+
{ text: "sky", duration: 2.0, recognise: true }
52+
]
53+
},
54+
{
55+
words: [
56+
{ text: "Twinkle", duration: 1.2, recognise: false },
57+
{ text: "twinkle", duration: 1.1, recognise: false },
58+
{ text: "little", duration: 1.5, recognise: true },
59+
{ text: "star", duration: 2.0, recognise: false }
60+
]
61+
},
62+
{
63+
words: [
64+
{ text: "How", duration: 0.49, recognise: true },
65+
{ text: "I", duration: 0.46, recognise: true },
66+
{ text: "wonder", duration: 1.32, recognise: true },
67+
{ text: "what", duration: 0.69, recognise: true },
68+
{ text: "you", duration: 0.46, recognise: true },
69+
{ text: "are", duration: 3.0, recognise: true }
70+
]
71+
}
72+
]
73+
};
1174

1275
// State management
1376
this.currentSentenceIndex = 0;
@@ -19,109 +82,6 @@ class LyricsEngine {
1982
this.onStop = null; // Callback for when animation should stop
2083
}
2184

22-
/**
23-
* Load lyrics data from the hardcoded lyrics-data.json file
24-
* @returns {Promise<boolean>} - True if loaded successfully, false otherwise
25-
*/
26-
async loadLyricsData() {
27-
try {
28-
const response = await fetch('lyrics-data.json');
29-
if (!response.ok) {
30-
throw new Error(`Failed to load lyrics-data.json: ${response.status} ${response.statusText}`);
31-
}
32-
33-
const data = await response.json();
34-
35-
// Validate data structure
36-
if (!this.validateLyricsData(data)) {
37-
throw new Error('Invalid lyrics data structure in lyrics-data.json');
38-
}
39-
40-
this.lyricsData = data;
41-
this.isDataLoaded = true;
42-
console.log('Lyrics data loaded successfully from lyrics-data.json');
43-
return true;
44-
45-
} catch (error) {
46-
console.error('Error loading lyrics-data.json:', error);
47-
48-
// Fallback to minimal default data
49-
this.lyricsData = {
50-
offset: 17,
51-
outro: 3,
52-
song_1_source: "song1.mp3",
53-
song_2_source: "song2.mp3",
54-
sentences: [{
55-
words: [{ text: "Loading failed...", duration: 1.0, recognise: false }]
56-
}]
57-
};
58-
this.isDataLoaded = false;
59-
return false;
60-
}
61-
}
62-
63-
/**
64-
* Validate lyrics data structure
65-
* @param {Object} data - Data to validate
66-
* @returns {boolean} - True if valid, false otherwise
67-
*/
68-
validateLyricsData(data) {
69-
if (!data || typeof data !== 'object') return false;
70-
if (typeof data.offset !== 'number') return false;
71-
if (typeof data.outro !== 'number') return false;
72-
if (typeof data.song_1_source !== 'string') return false;
73-
if (typeof data.song_2_source !== 'string') return false;
74-
if (!Array.isArray(data.sentences)) return false;
75-
76-
return data.sentences.every(sentence =>
77-
Array.isArray(sentence.words) &&
78-
sentence.words.every(word =>
79-
typeof word.text === 'string' &&
80-
typeof word.duration === 'number' &&
81-
typeof word.recognise === 'boolean'
82-
)
83-
);
84-
}
85-
86-
/**
87-
* Verify that audio sources are accessible
88-
* @returns {Promise<boolean>} - True if both audio sources are accessible
89-
*/
90-
async verifyAudioSources() {
91-
if (!this.lyricsData) {
92-
console.warn('No lyrics data available from lyrics-data.json for audio verification');
93-
return false;
94-
}
95-
96-
try {
97-
// Check if audio files exist/are accessible using HEAD requests
98-
const checkAudio = async (src) => {
99-
try {
100-
const response = await fetch(src, { method: 'HEAD' });
101-
return response.ok;
102-
} catch (error) {
103-
console.warn(`Audio source ${src} not accessible:`, error.message);
104-
return false;
105-
}
106-
};
107-
108-
const song1Available = await checkAudio(this.lyricsData.song_1_source);
109-
const song2Available = await checkAudio(this.lyricsData.song_2_source);
110-
111-
if (song1Available && song2Available) {
112-
console.log('All audio sources verified successfully');
113-
return true;
114-
} else {
115-
console.warn(`Audio verification failed - Song 1: ${song1Available}, Song 2: ${song2Available}`);
116-
return false;
117-
}
118-
119-
} catch (error) {
120-
console.error('Audio source verification error:', error);
121-
return false;
122-
}
123-
}
124-
12585
/**
12686
* Initialize the lyrics engine with DOM elements
12787
* @param {Object} elements - Object containing DOM element references
@@ -316,9 +276,9 @@ class LyricsEngine {
316276
animate() {
317277
if (!this.isPlaying) return;
318278

319-
// Safety check: ensure lyrics data is loaded
320-
if (!this.lyricsData || !this.isDataLoaded) {
321-
console.warn('Lyrics data not loaded, stopping animation');
279+
// Safety check: ensure lyrics data exists (should always be true now)
280+
if (!this.lyricsData) {
281+
console.error('Critical error: lyrics data missing');
322282
return;
323283
}
324284

0 commit comments

Comments
 (0)