Skip to content

Commit 50b82ba

Browse files
authored
handle chunked datatransfer in playlists
1 parent 8d416ae commit 50b82ba

File tree

2 files changed

+57
-24
lines changed

2 files changed

+57
-24
lines changed

src/Audio.cpp

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
*
44
* Created on: Oct 26.2018
55
*
6-
* Version 2.0.5d
7-
* Updated on: Aug 01.2022
6+
* Version 2.0.5e
7+
* Updated on: Aug 02.2022
88
* Author: Wolle (schreibfaul1)
99
*
1010
*/
@@ -300,7 +300,6 @@ void Audio::setDefaults() {
300300
FLACDecoder_FreeBuffers();
301301
AACDecoder_FreeBuffers();
302302
if(m_playlistBuff) {free(m_playlistBuff); m_playlistBuff = NULL;} // free if stream is not m3u8
303-
if(m_m3u8_lastEntry) {free(m_m3u8_lastEntry); m_m3u8_lastEntry = NULL;} // free if stream is not m3u8
304303
vector_clear_and_shrink(m_playlistURL);
305304
vector_clear_and_shrink(m_playlistContent);
306305
m_hashQueue.clear(); m_hashQueue.shrink_to_fit(); // uint32_t vector
@@ -569,6 +568,14 @@ bool Audio::httpPrint(const char* host) {
569568
if(m_f_ssl){ _client = static_cast<WiFiClient*>(&clientsecure); if(port == 80) port = 443;}
570569
else { _client = static_cast<WiFiClient*>(&client);}
571570

571+
if(!_client->connected()){
572+
AUDIO_INFO("The host has disconnected, reconnecting");
573+
if(!_client->connect(hostwoext, port)){
574+
log_e("connection lost");
575+
stopSong();
576+
return false;
577+
}
578+
}
572579
_client->print(rqh);
573580

574581
if(endsWith(extension, ".mp3")) m_expectedCodec = CODEC_MP3;
@@ -584,6 +591,7 @@ bool Audio::httpPrint(const char* host) {
584591
setDatamode(HTTP_RESPONSE_HEADER); // Handle header
585592
m_streamType = ST_WEBSTREAM;
586593
m_contentlength = 0;
594+
m_f_chunked = false;
587595

588596
if(hostwoext) {free(hostwoext); hostwoext = NULL;}
589597
if(extension) {free(extension); extension = NULL;}
@@ -2314,8 +2322,7 @@ void Audio::loop() {
23142322
if(host){
23152323
f_noNewHost = false;
23162324
timestamp1 = millis();
2317-
if(_client->connected()) httpPrint(host);
2318-
else connecttohost(host); // redirect from m3u8 or connection is broken
2325+
httpPrint(host);
23192326
}
23202327
else {
23212328
f_noNewHost = true;
@@ -2329,8 +2336,7 @@ void Audio::loop() {
23292336
if(f_noNewHost){
23302337
m_f_continue = false;
23312338
if(timestamp2 < millis()) {
2332-
if(_client->connected()) httpPrint(m_lastHost);
2333-
else connecttohost(m_lastHost);
2339+
httpPrint(m_lastHost);
23342340
}
23352341
}
23362342
else{
@@ -2352,6 +2358,22 @@ bool Audio::readPlayListData() {
23522358
if(m_datamode != AUDIO_PLAYLISTINIT) return false;
23532359
if(_client->available() == 0) return false;
23542360

2361+
uint32_t chunksize = 0;
2362+
if(m_f_chunked){
2363+
int b = 0;
2364+
while(true){
2365+
b = _client->read();
2366+
if(b < 0) break;
2367+
if(b == '\n') break;
2368+
if(b < '0') continue;
2369+
// We have received a hexadecimal character. Decode it and add to the result.
2370+
b = toupper(b) - '0'; // Be sure we have uppercase
2371+
if(b > 9) b = b - 7; // Translate A..F to 10..15
2372+
chunksize = (chunksize << 4) + b;
2373+
}
2374+
if(m_f_Log) log_i("chunksize %d", chunksize);
2375+
}
2376+
23552377
// reads the content of the playlist and stores it in the vector m_contentlength
23562378
// m_contentlength is a table of pointers to the lines
23572379
char pl[512]; // playlistLine
@@ -2381,25 +2403,25 @@ bool Audio::readPlayListData() {
23812403
if(ctime + timeout < millis()) {log_e("timeout"); goto exit;}
23822404
} // inner while
23832405

2384-
if(m_contentlength > 0){
2385-
// we have one line only, terminate all crap
2386-
if(m_contentlength < strlen(pl)) {log_e("%i", m_contentlength); pl[m_contentlength] = '\0';}
2387-
// we have more line but no '\n' at the and -> terminate all crap
2388-
else if(m_contentlength < ctl){
2389-
int diff = ctl - m_contentlength;
2390-
int lastpos = strlen(pl) - diff;
2391-
pl[lastpos] = '\0';
2392-
}
2393-
}
2406+
// if(m_contentlength > 0){
2407+
// // we have one line only, terminate all crap
2408+
// if(m_contentlength < strlen(pl)) {log_e("%i", m_contentlength); pl[m_contentlength] = '\0';}
2409+
// // we have more line but no '\n' at the and -> terminate all crap
2410+
// else if(m_contentlength < ctl){
2411+
// int diff = ctl - m_contentlength;
2412+
// int lastpos = strlen(pl) - diff;
2413+
// pl[lastpos] = '\0';
2414+
// }
2415+
// }
23942416

23952417
if(startsWith(pl, "<!DOCTYPE")) {AUDIO_INFO("url is a webpage!"); goto exit;}
23962418
if(strlen(pl) > 0) m_playlistContent.push_back(strdup((const char*)pl));
23972419
if(m_playlistContent.size() == 100){
23982420
if(m_f_Log) log_i("the maximum number of lines in the playlist has been reached");
23992421
break;
24002422
}
2401-
if(ctl == m_contentlength){break;}
2402-
if(!m_contentlength && !_client->available()) break;
2423+
if(ctl == m_contentlength){while(_client->available()) _client->read(); break;} // read '\n\n' if exists
2424+
if(ctl == chunksize) {while(_client->available()) _client->read(); break;}
24032425

24042426
} // outer while6nUfOrsqhhT-331
24052427
lines = m_playlistContent.size();
@@ -3265,7 +3287,7 @@ void Audio::processWebStreamTS() {
32653287
if(loopCnt > 200000) { // wait several seconds
32663288
loopCnt = 0;
32673289
AUDIO_INFO("Stream lost -> try new connection");
3268-
connecttohost(m_lastHost);
3290+
httpPrint(m_lastHost);
32693291
return;
32703292
}
32713293
}
@@ -3366,7 +3388,7 @@ void Audio::processWebStreamHLS() {
33663388
if(loopCnt > 200000) { // wait several seconds
33673389
loopCnt = 0;
33683390
AUDIO_INFO("Stream lost -> try new connection");
3369-
connecttohost(m_lastHost);
3391+
httpPrint(m_lastHost);
33703392
return;
33713393
}
33723394
}
@@ -3495,7 +3517,19 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque
34953517
if(pos >= 0){
34963518
const char* c_host = (rhl + pos);
34973519
if(strcmp(c_host, m_lastHost) != 0) { // prevent a loop
3498-
if(m_playlistFormat == FORMAT_M3U8) {strcpy(m_lastHost, c_host); m_f_m3u8data = true;} // extension has changed but host is the same?
3520+
int pos_slash = indexOf(c_host, "/", 9);
3521+
if(pos_slash > 9){
3522+
if(!strncmp(c_host, m_lastHost, posColon)){
3523+
AUDIO_INFO("redirect to new extension at existing host \"%s\"", c_host);
3524+
if(m_playlistFormat == FORMAT_M3U8) {
3525+
strcpy(m_lastHost, c_host);
3526+
m_f_m3u8data = true;
3527+
}
3528+
httpPrint(c_host);
3529+
while(_client->available()) _client->read(); // empty client buffer
3530+
return true;
3531+
}
3532+
}
34993533
AUDIO_INFO("redirect to new host \"%s\"", c_host);
35003534
connecttohost(c_host);
35013535
return true;

src/Audio.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Audio.h
33
*
44
* Created on: Oct 28,2018
5-
* Updated on: Aug 01,2022
5+
* Updated on: Aug 02,2022
66
* Author: Wolle (schreibfaul1)
77
*/
88

@@ -464,7 +464,6 @@ class Audio : private AudioBuffer{
464464
char chbuf[512 + 128]; // must be greater than m_lastHost #254
465465
char m_lastHost[512]; // Store the last URL to a webstream
466466
char* m_playlistBuff = NULL; // stores playlistdata
467-
char* m_m3u8_lastEntry = nullptr; // compare sequencenumbers
468467
const uint16_t m_plsBuffEntryLen = 256; // length of each entry in playlistBuff
469468
filter_t m_filter[3]; // digital filters
470469
int m_LFcount = 0; // Detection of end of header

0 commit comments

Comments
 (0)