CosmickVisions commited on
Commit
dfee44a
·
verified ·
1 Parent(s): 08818b8

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +249 -22
index.html CHANGED
@@ -1,29 +1,256 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
-
4
  <head>
5
- <meta charset="UTF-8" />
6
- <link rel="stylesheet" href="style.css" />
7
-
8
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
9
- <title>Transformers.js - Object Detection</title>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  </head>
11
-
12
  <body>
13
- <h1>Object Detection w/ 🤗 Transformers.js</h1>
14
- <label id="container" for="upload">
15
- <svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
16
- <path fill="#000"
17
- d="M3.5 24.3a3 3 0 0 1-1.9-.8c-.5-.5-.8-1.2-.8-1.9V2.9c0-.7.3-1.3.8-1.9.6-.5 1.2-.7 2-.7h18.6c.7 0 1.3.2 1.9.7.5.6.7 1.2.7 2v18.6c0 .7-.2 1.4-.7 1.9a3 3 0 0 1-2 .8H3.6Zm0-2.7h18.7V2.9H3.5v18.7Zm2.7-2.7h13.3c.3 0 .5 0 .6-.3v-.7l-3.7-5a.6.6 0 0 0-.6-.2c-.2 0-.4 0-.5.3l-3.5 4.6-2.4-3.3a.6.6 0 0 0-.6-.3c-.2 0-.4.1-.5.3l-2.7 3.6c-.1.2-.2.4 0 .7.1.2.3.3.6.3Z">
18
- </path>
19
- </svg>
20
- Click to upload image
21
- <label id="example">(or try example)</label>
22
- </label>
23
- <label id="status">Loading model...</label>
24
- <input id="upload" type="file" accept="image/*" />
25
-
26
- <script src="index.js" type="module"></script>
27
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
 
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Cosmick-Radio</title>
7
+ <style>
8
+ body { margin: 0; font-family: Arial, sans-serif; transition: background-color 0.5s, color 0.5s; }
9
+ .container { display: flex; flex-direction: column; height: 100vh; padding: 20px; background: white; color: #1f2937; }
10
+ .dark-mode { background-color: #1f2937; color: white; }
11
+ .app-bar { display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom: 1px solid rgba(156, 163, 175, 0.2); }
12
+ .main-content { display: flex; flex: 1; overflow: hidden; }
13
+ .player { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; }
14
+ .station-box {
15
+ width: 200px;
16
+ height: 200px;
17
+ background: white;
18
+ border: 3px solid red;
19
+ border-radius: 10px;
20
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
21
+ margin-bottom: 20px;
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: center;
25
+ }
26
+ .station-name-text {
27
+ font-size: 24px;
28
+ font-weight: bold;
29
+ text-align: center;
30
+ background: linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet);
31
+ -webkit-background-clip: text;
32
+ -webkit-text-fill-color: transparent;
33
+ }
34
+ .station-box.playing { animation: pulse 3s infinite; }
35
+ .controls button { padding: 10px; margin: 0 10px; background: #9333ea; color: white; border: none; border-radius: 50%; cursor: pointer; }
36
+ .controls button:hover { background: #7e22ce; }
37
+ .volume { display: flex; align-items: center; margin: 20px 0; }
38
+ .volume input { width: 200px; margin: 0 10px; }
39
+ .actions button { margin: 0 10px; background: none; border: none; cursor: pointer; }
40
+ .liked { color: #ef4444; fill: #ef4444; }
41
+ .panel { width: 300px; background: rgba(0, 0, 0, 0.1); padding: 20px; overflow-y: auto; }
42
+ .station-item { display: flex; align-items: center; padding: 10px; }
43
+ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } }
44
+ </style>
45
  </head>
 
46
  <body>
47
+ <div id="container" class="container">
48
+ <div class="app-bar">
49
+ <div>
50
+ <svg width="24" height="24" viewBox="0 0 24 24" style="display:inline-block; vertical-align:middle;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"/></svg>
51
+ <h1 style="display:inline-block; margin-left:5px;">Cosmick-Radio</h1>
52
+ </div>
53
+ <div>
54
+ <button id="prefs-btn"><svg width="24" height="24" viewBox="0 0 24 24"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg></button>
55
+ <button id="theme-btn"><svg width="24" height="24" viewBox="0 0 24 24"><path d="M12 3v1.5M12 19.5V21M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M3 12h1.5M19.5 12H21M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42M12 7a5 5 0 100 10 5 5 0 000-10z"/></svg></button>
56
+ </div>
57
+ </div>
58
+ <div class="main-content">
59
+ <div class="player">
60
+ <div id="station-box" class="station-box">
61
+ <span id="station-name-text" class="station-name-text">Radio Paradise</span>
62
+ </div>
63
+ <div id="station-info" style="text-align:center;">
64
+ <span id="frequency">N/A</span>
65
+ <span id="status" style="display:inline-block; width:8px; height:8px; border-radius:50%; background:red; margin-left:5px;"></span>
66
+ <h2 id="station-name">Radio Paradise</h2>
67
+ <p id="genre">Eclectic</p>
68
+ <p id="description">Eclectic mix of rock, world, and more</p>
69
+ </div>
70
+ <div class="volume">
71
+ <svg width="20" height="20" viewBox="0 0 24 24"><path d="M18.5 12c0-1.77-.77-3.37-2-4.46V4.46c2.69 1.46 4.5 4.36 4.5 7.54s-1.81 6.08-4.5 7.54v-3.08c1.23-1.09 2-2.69 2-4.46zM3 9v6h4l5 5V4L7 9H3zm11.5 3c0 1.38-.73 2.6-1.85 3.27l1.39 1.39C15.87 15.53 17 13.82 17 12s-1.13-3.53-2.94-4.66l-1.39 1.39c1.12.67 1.83 1.89 1.83 3.27z"/></svg>
72
+ <input type="range" id="volume" min="0" max="100" value="70">
73
+ <span id="volume-value">70%</span>
74
+ </div>
75
+ <div class="controls">
76
+ <button id="prev-btn"><svg width="24" height="24" viewBox="0 0 24 24"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg></button>
77
+ <button id="play-pause-btn"><svg width="28" height="28" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg></button>
78
+ <button id="next-btn"><svg width="24" height="24" viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg></button>
79
+ </div>
80
+ <div class="actions" style="margin-top:20px;">
81
+ <button id="like-btn"><svg width="24" height="24" viewBox="0 0 24 24"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg></button>
82
+ <button id="share-btn"><svg width="24" height="24" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.70l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31 2.92-2.92s-1.31-2.92-2.92-2.92z"/></svg></button>
83
+ <button id="recommend-btn"><svg width="24" height="24" viewBox="0 0 24 24"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg></button>
84
+ </div>
85
+ </div>
86
+ <div id="recommend-panel" class="panel" style="display:none;">
87
+ <h3>AI Recommendations</h3>
88
+ <button id="close-recommend">×</button>
89
+ <div id="recommend-list"></div>
90
+ </div>
91
+ <div id="prefs-panel" class="panel" style="display:none;">
92
+ <h3>AI Personalization</h3>
93
+ <button id="close-prefs">×</button>
94
+ <p>Preferences coming soon!</p>
95
+ </div>
96
+ </div>
97
+ </div>
98
+
99
+ <script src="https://cdn.jsdelivr.net/npm/@huggingface/transformers@latest/dist/transformers.min.js"></script>
100
+ <script>
101
+ const stations = [
102
+ { id: 1, name: "Radio Paradise", genre: "Eclectic", frequency: "N/A", streamUrl: "http://stream.radioparadise.com/mp3-192", description: "Eclectic mix of rock, world, and more" },
103
+ { id: 2, name: "SomaFM Groove Salad", genre: "Ambient", frequency: "N/A", streamUrl: "http://ice1.somafm.com/groovesalad-128-mp3", description: "Chilled beats and ambient vibes" },
104
+ // Classical Stations
105
+ { id: 3, name: "Classical MPR", genre: "Classical", frequency: "N/A", streamUrl: "http://cms.stream.publicradio.org/cms.mp3", description: "Classical music from Minnesota Public Radio" },
106
+ { id: 4, name: "WFMT Classical", genre: "Classical", frequency: "N/A", streamUrl: "http://stream.wfmt.com/main-mp3", description: "Classical music from Chicago" },
107
+ { id: 5, name: "BBC Radio 3", genre: "Classical", frequency: "N/A", streamUrl: "http://bbcmedia.ic.llnwd.net/stream/bbcmedia_radio3_mf_p", description: "Classical music from the BBC" },
108
+ { id: 6, name: "WCRB Classical", genre: "Classical", frequency: "N/A", streamUrl: "http://audio.wgbh.org:8004/stream", description: "Boston’s classical music station" },
109
+ { id: 7, name: "Radio Swiss Classic", genre: "Classical", frequency: "N/A", streamUrl: "http://stream.srg-ssr.ch/m/rsc_de/mp3_128", description: "Swiss classical music" },
110
+ { id: 8, name: "KUSC Classical", genre: "Classical", frequency: "N/A", streamUrl: "http://stream.kusc.org/kusc-128k.mp3", description: "Classical music from Los Angeles" },
111
+ { id: 9, name: "Classical WETA", genre: "Classical", frequency: "N/A", streamUrl: "http://weta.streamguys1.com/classical", description: "Classical music from Washington, DC" },
112
+ { id: 10, name: "France Musique", genre: "Classical", frequency: "N/A", streamUrl: "http://direct.francemusique.fr/live/francemusique-midfi.mp3", description: "French classical music" },
113
+ // Smooth Jazz Stations
114
+ { id: 11, name: "Smooth Jazz Florida", genre: "Smooth Jazz", frequency: "N/A", streamUrl: "http://smoothjazz.cdnstream1.com/2524_128.mp3", description: "Smooth jazz tunes from Florida" },
115
+ { id: 12, name: "Jazz24", genre: "Smooth Jazz", frequency: "N/A", streamUrl: "http://live.wostreaming.net/direct/ppm-jazz24aac256-ibc1", description: "24/7 smooth jazz" },
116
+ { id: 13, name: "WHOV 88.1 Hampton Radio", genre: "Smooth Jazz", frequency: "88.1 FM", streamUrl: "http://whov.streamguys1.com/live", description: "Smooth jazz from Hampton, Virginia" },
117
+ { id: 14, name: "Smooth Jazz Global", genre: "Smooth Jazz", frequency: "N/A", streamUrl: "http://smoothjazzglobal.streamguys1.com/sjglobal", description: "Global smooth jazz hits" },
118
+ { id: 15, name: "The Wave Smooth Jazz", genre: "Smooth Jazz", frequency: "N/A", streamUrl: "http://stream.zeno.fm/xv8nq5v5v5zuv", description: "Relaxing smooth jazz" },
119
+ { id: 16, name: "Jazz FM Smooth", genre: "Smooth Jazz", frequency: "N/A", streamUrl: "http://listen.jazzfm.com/jazzsmooth", description: "Smooth jazz from the UK" },
120
+ { id: 17, name: "Smooth Jazz 247", genre: "Smooth Jazz", frequency: "N/A", streamUrl: "http://stream.smoothjazz247.com/live", description: "Non-stop smooth jazz" },
121
+ // Additional Stations
122
+ { id: 18, name: "KEXP", genre: "Eclectic", frequency: "N/A", streamUrl: "http://live-mp3-128.kexp.org/kexp128.mp3", description: "Eclectic music from Seattle" },
123
+ { id: 19, name: "Hot 108 Jamz", genre: "Hip Hop", frequency: "N/A", streamUrl: "http://108.61.30.179:4010/", description: "Hip hop hits" },
124
+ { id: 20, name: "Virgin Radio UK", genre: "Pop", frequency: "N/A", streamUrl: "http://radio.virginradio.co.uk/stream", description: "Latest pop hits" },
125
+ ];
126
+ let currentStation = 0;
127
+ let isPlaying = false;
128
+ let likedStations = [];
129
+ let isDarkMode = false;
130
+ const audio = new Audio();
131
+ const container = document.getElementById('container');
132
+ const stationBox = document.getElementById('station-box');
133
+ const stationNameText = document.getElementById('station-name-text');
134
+ const frequency = document.getElementById('frequency');
135
+ const status = document.getElementById('status');
136
+ const stationName = document.getElementById('station-name');
137
+ const genre = document.getElementById('genre');
138
+ const description = document.getElementById('description');
139
+ const volume = document.getElementById('volume');
140
+ const volumeValue = document.getElementById('volume-value');
141
+ const playPauseBtn = document.getElementById('play-pause-btn');
142
+ const likeBtn = document.getElementById('like-btn');
143
+ const recommendPanel = document.getElementById('recommend-panel');
144
+ const recommendList = document.getElementById('recommend-list');
145
+ const prefsPanel = document.getElementById('prefs-panel');
146
+ let classifier;
147
+
148
+ (async () => {
149
+ classifier = await transformers.pipeline('sentiment-analysis', 'Xenova/distilbert-base-uncased-finetuned-sst-2-english');
150
+ console.log('Sentiment analysis model loaded');
151
+ updateUI();
152
+ })();
153
+
154
+ function updateUI() {
155
+ const station = stations[currentStation];
156
+ stationNameText.textContent = station.name;
157
+ frequency.textContent = `${station.frequency}`;
158
+ status.style.background = isPlaying ? '#10b981' : '#ef4444';
159
+ stationName.textContent = station.name;
160
+ genre.textContent = station.genre;
161
+ description.textContent = station.description;
162
+ stationBox.classList.toggle('playing', isPlaying);
163
+ playPauseBtn.innerHTML = isPlaying ? '<svg width="28" height="28" viewBox="0 0 24 24"><path d="M6 4h4v16H6zM14 4h4v16h-4z"/></svg>' : '<svg width="28" height="28" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>';
164
+ likeBtn.classList.toggle('liked', likedStations.includes(station.id));
165
+ likeBtn.querySelector('svg').setAttribute('fill', likedStations.includes(station.id) ? '#ef4444' : 'none');
166
+ container.className = `container ${isDarkMode ? 'dark-mode' : ''}`;
167
+ }
168
+
169
+ function togglePlay() {
170
+ if (isPlaying) {
171
+ audio.pause();
172
+ } else {
173
+ audio.src = stations[currentStation].streamUrl;
174
+ audio.play().catch(e => console.error('Playback failed:', e));
175
+ }
176
+ isPlaying = !isPlaying;
177
+ updateUI();
178
+ }
179
+
180
+ function changeStation(direction) {
181
+ audio.pause();
182
+ currentStation = direction === 'next'
183
+ ? (currentStation + 1) % stations.length
184
+ : (currentStation - 1 + stations.length) % stations.length;
185
+ isPlaying = true;
186
+ audio.src = stations[currentStation].streamUrl;
187
+ audio.play().catch(e => console.error('Playback failed:', e));
188
+ updateUI();
189
+ }
190
 
191
+ volume.addEventListener('input', () => {
192
+ audio.volume = volume.value / 100;
193
+ volumeValue.textContent = `${volume.value}%`;
194
+ });
195
+ audio.volume = volume.value / 100;
196
+
197
+ likeBtn.addEventListener('click', () => {
198
+ const stationId = stations[currentStation].id;
199
+ if (likedStations.includes(stationId)) {
200
+ likedStations = likedStations.filter(id => id !== stationId);
201
+ } else {
202
+ likedStations.push(stationId);
203
+ }
204
+ updateUI();
205
+ if (recommendPanel.style.display === 'block') updateRecommendations();
206
+ });
207
+
208
+ document.getElementById('theme-btn').addEventListener('click', () => {
209
+ isDarkMode = !isDarkMode;
210
+ updateUI();
211
+ });
212
+
213
+ playPauseBtn.addEventListener('click', togglePlay);
214
+ document.getElementById('prev-btn').addEventListener('click', () => changeStation('prev'));
215
+ document.getElementById('next-btn').addEventListener('click', () => changeStation('next'));
216
+
217
+ document.getElementById('recommend-btn').addEventListener('click', () => {
218
+ recommendPanel.style.display = recommendPanel.style.display === 'block' ? 'none' : 'block';
219
+ if (recommendPanel.style.display === 'block') updateRecommendations();
220
+ });
221
+
222
+ document.getElementById('close-recommend').addEventListener('click', () => {
223
+ recommendPanel.style.display = 'none';
224
+ });
225
+
226
+ async function updateRecommendations() {
227
+ if (!classifier) return;
228
+ recommendList.innerHTML = 'Loading...';
229
+ const listenedStations = stations.filter(s => likedStations.includes(s.id));
230
+ const descriptions = listenedStations.map(s => s.description);
231
+ const sentiments = await classifier(descriptions);
232
+ const recommended = stations.filter(station =>
233
+ !likedStations.includes(station.id) &&
234
+ sentiments.some((s, idx) => s.label === 'POSITIVE' && station.genre === listenedStations[idx].genre)
235
+ );
236
+ recommendList.innerHTML = recommended.length ? recommended.map(station => `
237
+ <div class="station-item">
238
+ <div style="width:50px; height:50px; background:white; border:2px solid red; border-radius:5px; margin-right:10px;"></div>
239
+ <div>
240
+ <h4>${station.name}</h4>
241
+ <p>${station.genre} • ${station.frequency}</p>
242
+ </div>
243
+ </div>
244
+ `).join('') : 'No recommendations yet. Like some stations!';
245
+ }
246
+
247
+ document.getElementById('prefs-btn').addEventListener('click', () => {
248
+ prefsPanel.style.display = prefsPanel.style.display === 'block' ? 'none' : 'block';
249
+ });
250
+
251
+ document.getElementById('close-prefs').addEventListener('click', () => {
252
+ prefsPanel.style.display = 'none';
253
+ });
254
+ </script>
255
+ </body>
256
  </html>