Skip to content

Commit 6e17383

Browse files
authored
Support Safari streaming behaviour (#2142)
As explained in https://stackoverflow.com/a/79309100
1 parent 44680eb commit 6e17383

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/AudioTools/CoreAudio/AudioHttp/AudioServer.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,17 @@ class AudioServerT {
130130
if (callback == nullptr) {
131131
LOGD("copy data...");
132132
if (converter_ptr == nullptr) {
133-
copier.copy();
133+
sent += copier.copy();
134134
} else {
135-
copier.copy(*converter_ptr);
135+
sent += copier.copy(*converter_ptr);
136136
}
137+
138+
if (max_bytes > 0 && sent >= max_bytes) {
139+
LOGI("range exhausted...");
140+
client_obj.stop();
141+
active = false;
142+
}
143+
137144
// if we limit the size of the WAV the encoder gets automatically
138145
// closed when all has been sent
139146
if (!client_obj) {
@@ -176,6 +183,8 @@ class AudioServerT {
176183
Client client_obj;
177184
char *password = nullptr;
178185
char *network = nullptr;
186+
size_t max_bytes = 0;
187+
size_t sent = 0;
179188

180189
// Content
181190
const char *content_type = nullptr;
@@ -211,10 +220,17 @@ class AudioServerT {
211220

212221
virtual void sendReplyHeader() {
213222
TRACED();
223+
214224
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
215225
// and a content-type so the client knows what's coming, then a blank line:
216-
client_obj.println("HTTP/1.1 200 OK");
217-
LOGI("Reply: HTTP/1.1 200 OK");
226+
char *response;
227+
if (max_bytes > 0) {
228+
response = "HTTP/1.1 206 OK";
229+
} else {
230+
response = "HTTP/1.1 200 OK";
231+
}
232+
client_obj.println(response);
233+
LOGI(response);
218234
if (content_type != nullptr) {
219235
client_obj.print("Content-type:");
220236
client_obj.println(content_type);
@@ -250,18 +266,29 @@ class AudioServerT {
250266
LOGI("New Client:"); // print a message out the serial port
251267
String currentLine =
252268
""; // make a String to hold incoming data from the client
269+
long firstbyte = 0;
270+
long lastbyte = 0;
253271
while (client_obj.connected()) { // loop while the client's connected
254272
if (client_obj
255273
.available()) { // if there's bytes to read from the client,
256274
char c = client_obj.read(); // read a byte, then
257275
if (c == '\n') { // if the byte is a newline character
258276
LOGI("Request: %s", currentLine.c_str());
277+
if (currentLine.startsWith(String("Range: bytes="))) {
278+
int minuspos = currentLine.indexOf('-', 13);
279+
280+
// toInt returns 0 if it's an invalid conversion, so it's "safe"
281+
firstbyte = currentLine.substring(13, minuspos).toInt();
282+
lastbyte = currentLine.substring(minuspos + 1).toInt();
283+
}
259284
// if the current line is blank, you got two newline characters in a
260285
// row. that's the end of the client HTTP request, so send a
261286
// response:
262287
if (currentLine.length() == 0) {
263288
sendReplyHeader();
264289
sendReplyContent();
290+
max_bytes = lastbyte - firstbyte;
291+
sent = 0;
265292
// break out of the while loop:
266293
break;
267294
} else { // if you got a newline, then clear currentLine:

0 commit comments

Comments
 (0)