shoom013 commited on
Commit
dc1e92f
·
verified ·
1 Parent(s): 61f28b1

Create test.html

Browse files
Files changed (1) hide show
  1. test.html +210 -0
test.html ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <title>FoxDot Stream Test</title>
6
+ <style>
7
+ body {
8
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
9
+ padding: 40px;
10
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
11
+ color: white;
12
+ min-height: 100vh;
13
+ margin: 0;
14
+ }
15
+
16
+ .container {
17
+ max-width: 600px;
18
+ margin: 0 auto;
19
+ background: rgba(255, 255, 255, 0.1);
20
+ backdrop-filter: blur(10px);
21
+ padding: 30px;
22
+ border-radius: 15px;
23
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
24
+ }
25
+
26
+ h1 {
27
+ text-align: center;
28
+ margin-bottom: 10px;
29
+ }
30
+
31
+ .subtitle {
32
+ text-align: center;
33
+ opacity: 0.8;
34
+ margin-bottom: 30px;
35
+ }
36
+
37
+ audio {
38
+ width: 100%;
39
+ margin: 20px 0;
40
+ border-radius: 10px;
41
+ }
42
+
43
+ .status {
44
+ padding: 15px;
45
+ background: rgba(0, 0, 0, 0.3);
46
+ border-radius: 8px;
47
+ margin: 15px 0;
48
+ }
49
+
50
+ .status-indicator {
51
+ display: inline-block;
52
+ width: 12px;
53
+ height: 12px;
54
+ border-radius: 50%;
55
+ margin-right: 8px;
56
+ animation: pulse 2s ease-in-out infinite;
57
+ }
58
+
59
+ .status-connecting {
60
+ background: #ffd700;
61
+ }
62
+
63
+ .status-playing {
64
+ background: #00ff00;
65
+ }
66
+
67
+ .status-error {
68
+ background: #ff0000;
69
+ animation: none;
70
+ }
71
+
72
+ .status-buffering {
73
+ background: #ffa500;
74
+ }
75
+
76
+ @keyframes pulse {
77
+
78
+ 0%,
79
+ 100% {
80
+ opacity: 1;
81
+ }
82
+
83
+ 50% {
84
+ opacity: 0.5;
85
+ }
86
+ }
87
+
88
+ .info {
89
+ background: rgba(0, 0, 0, 0.2);
90
+ padding: 15px;
91
+ border-radius: 8px;
92
+ margin-top: 20px;
93
+ font-size: 14px;
94
+ }
95
+
96
+ .info code {
97
+ background: rgba(0, 0, 0, 0.3);
98
+ padding: 2px 6px;
99
+ border-radius: 3px;
100
+ font-family: 'Courier New', monospace;
101
+ }
102
+ </style>
103
+ </head>
104
+
105
+ <body>
106
+ <div class="container">
107
+ <h1>🎵 FoxDot Audio Stream</h1>
108
+ <p class="subtitle">Live audio streaming from SuperCollider</p>
109
+
110
+ <audio id="audioPlayer" controls autoplay>
111
+ <source src="http://localhost:8000/stream" type="audio/mpeg">
112
+ Your browser does not support the audio element.
113
+ </audio>
114
+
115
+ <div class="status">
116
+ <span id="statusIndicator" class="status-indicator status-connecting"></span>
117
+ <strong>Status:</strong> <span id="statusText">Connecting...</span>
118
+ </div>
119
+
120
+ <div class="info">
121
+ <strong>Stream Info:</strong><br>
122
+ URL: <code id="streamUrl">http://localhost/stream</code><br>
123
+ Format: <code>MP3 (128kbps)</code><br>
124
+ Source: <code>SuperCollider → JACK → FFmpeg → Icecast</code>
125
+ </div>
126
+
127
+ <div class="info" id="debugInfo" style="display: none;">
128
+ <strong>Debug Info:</strong><br>
129
+ <div id="debugText"></div>
130
+ </div>
131
+ </div>
132
+
133
+ <script>
134
+ const audio = document.getElementById('audioPlayer');
135
+ const statusText = document.getElementById('statusText');
136
+ const statusIndicator = document.getElementById('statusIndicator');
137
+ const debugInfo = document.getElementById('debugInfo');
138
+ const debugText = document.getElementById('debugText');
139
+
140
+ function updateStatus(status, message) {
141
+ statusText.innerText = message;
142
+ statusIndicator.className = 'status-indicator status-' + status;
143
+ }
144
+
145
+ function log(message) {
146
+ const timestamp = new Date().toLocaleTimeString();
147
+ debugText.innerHTML += `[${timestamp}] ${message}<br>`;
148
+ debugInfo.style.display = 'block';
149
+ console.log(message);
150
+ }
151
+
152
+ audio.onloadstart = () => {
153
+ updateStatus('connecting', 'Loading stream...');
154
+ log('Loading stream from /stream');
155
+ };
156
+
157
+ audio.oncanplay = () => {
158
+ updateStatus('playing', 'Ready to play');
159
+ log('Stream is ready to play');
160
+ };
161
+
162
+ audio.onplaying = () => {
163
+ updateStatus('playing', 'Playing ♪');
164
+ log('Stream is playing');
165
+ };
166
+
167
+ audio.onwaiting = () => {
168
+ updateStatus('buffering', 'Buffering...');
169
+ log('Buffering stream data');
170
+ };
171
+
172
+ audio.onpause = () => {
173
+ updateStatus('connecting', 'Paused');
174
+ log('Stream paused');
175
+ };
176
+
177
+ audio.onerror = (e) => {
178
+ updateStatus('error', 'Error loading stream');
179
+ const error = audio.error;
180
+ let errorMsg = 'Unknown error';
181
+ if (error) {
182
+ switch (error.code) {
183
+ case 1: errorMsg = 'MEDIA_ERR_ABORTED - Playback aborted'; break;
184
+ case 2: errorMsg = 'MEDIA_ERR_NETWORK - Network error'; break;
185
+ case 3: errorMsg = 'MEDIA_ERR_DECODE - Decoding error'; break;
186
+ case 4: errorMsg = 'MEDIA_ERR_SRC_NOT_SUPPORTED - Stream not supported'; break;
187
+ }
188
+ }
189
+ log(`ERROR: ${errorMsg}`);
190
+
191
+ // Try to get more info about the stream
192
+ fetch('/stream', { method: 'HEAD' })
193
+ .then(response => {
194
+ log(`Stream endpoint status: ${response.status}`);
195
+ log(`Content-Type: ${response.headers.get('content-type')}`);
196
+ })
197
+ .catch(err => {
198
+ log(`Cannot reach stream endpoint: ${err.message}`);
199
+ });
200
+ };
201
+
202
+ // Show current URL
203
+ document.getElementById('streamUrl').innerText = window.location.origin + '/stream';
204
+
205
+ // Initial log
206
+ log('Page loaded, attempting to connect to stream');
207
+ </script>
208
+ </body>
209
+
210
+ </html>