Skip to content

Commit e7373ed

Browse files
committed
Some m3u8s content are not parsed correctly (Issue #935)
1 parent 30e06dc commit e7373ed

File tree

2 files changed

+41
-19
lines changed

2 files changed

+41
-19
lines changed

src/Audio.cpp

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Created on: Oct 28.2018
55
*
66
* Version 3.0.13zd
7-
* Updated on: Dec 29.2024
7+
* Updated on: Dec 30.2024
88
* Author: Wolle (schreibfaul1)
99
*
1010
*/
@@ -732,15 +732,19 @@ bool Audio::httpPrint(const char* host) {
732732
}
733733
}
734734
_client->print(rqh);
735-
if(endsWith(extension, ".mp3")) m_expectedCodec = CODEC_MP3;
736-
if(endsWith(extension, ".aac")) m_expectedCodec = CODEC_AAC;
737-
if(endsWith(extension, ".wav")) m_expectedCodec = CODEC_WAV;
738-
if(endsWith(extension, ".m4a")) m_expectedCodec = CODEC_M4A;
739-
if(endsWith(extension, ".flac")) m_expectedCodec = CODEC_FLAC;
740-
if(endsWith(extension, ".asx")) m_expectedPlsFmt = FORMAT_ASX;
741-
if(endsWith(extension, ".m3u")) m_expectedPlsFmt = FORMAT_M3U;
742-
if(indexOf( extension, ".m3u8") >= 0) m_expectedPlsFmt = FORMAT_M3U8;
743-
if(endsWith(extension, ".pls")) m_expectedPlsFmt = FORMAT_PLS;
735+
736+
if( endsWith(extension, ".mp3")) m_expectedCodec = CODEC_MP3;
737+
else if(endsWith(extension, ".aac")) m_expectedCodec = CODEC_AAC;
738+
else if(endsWith(extension, ".wav")) m_expectedCodec = CODEC_WAV;
739+
else if(endsWith(extension, ".m4a")) m_expectedCodec = CODEC_M4A;
740+
else if(endsWith(extension, ".flac")) m_expectedCodec = CODEC_FLAC;
741+
else m_expectedCodec = CODEC_NONE;
742+
743+
if( endsWith(extension, ".asx")) m_expectedPlsFmt = FORMAT_ASX;
744+
else if(endsWith(extension, ".m3u")) m_expectedPlsFmt = FORMAT_M3U;
745+
else if(indexOf( extension, ".m3u8") >= 0) m_expectedPlsFmt = FORMAT_M3U8;
746+
else if(endsWith(extension, ".pls")) m_expectedPlsFmt = FORMAT_PLS;
747+
else m_expectedPlsFmt = FORMAT_NONE;
744748

745749
m_dataMode = HTTP_RESPONSE_HEADER; // Handle header
746750
m_streamType = ST_WEBSTREAM;
@@ -3422,7 +3426,7 @@ void Audio::processWebStreamTS() {
34223426
static bool f_firstPacket;
34233427
static bool f_chunkFinished;
34243428
static uint32_t byteCounter; // count received data
3425-
static uint8_t ts_packet[188]; // m3u8 transport stream is 188 bytes long
3429+
static uint8_t ts_packet[188]; // m3u8 transport stream is always 188 bytes long
34263430
uint8_t ts_packetStart = 0;
34273431
uint8_t ts_packetLength = 0;
34283432
static uint8_t ts_packetPtr = 0;
@@ -3445,13 +3449,23 @@ void Audio::processWebStreamTS() {
34453449

34463450
availableBytes = _client->available();
34473451
if(availableBytes) {
3452+
3453+
/* If the m3u8 stream uses 'chunked data transfer' no content length is supplied. Then the chunk size determines the audio data to be processed.
3454+
However, the chunk size in some streams is limited to 32768 bytes, although the chunk can be larger. Then the chunk size is
3455+
calculated again. The data used to calculate (here readedBytes) the chunk size is not part of it.
3456+
*/
34483457
uint8_t readedBytes = 0;
3449-
if(m_f_chunked) chunkSize = chunkedDataTransfer(&readedBytes);
3450-
int res = _client->read(ts_packet + ts_packetPtr, ts_packetsize - ts_packetPtr);
3458+
uint32_t minBytes = 0;
3459+
if(m_f_chunked && chunkSize == byteCounter) chunkSize += chunkedDataTransfer(&readedBytes);
3460+
if(chunkSize) minBytes = min3(availableBytes, ts_packetsize - ts_packetPtr, chunkSize - byteCounter);
3461+
else minBytes = min(availableBytes, (uint32_t)(ts_packetsize - ts_packetPtr));
3462+
3463+
int res = _client->read(ts_packet + ts_packetPtr, minBytes);
34513464
if(res > 0) {
34523465
ts_packetPtr += res;
34533466
byteCounter += res;
3454-
if(ts_packetPtr < ts_packetsize) return;
3467+
if((chunkSize == byteCounter) && (chunkSize % 32768 == 0)) {return;} // recalculate chunk size
3468+
if(ts_packetPtr < ts_packetsize) return; // not enough data yet, the process must be repeated if the packet size (188 bytes) is not reached
34553469
ts_packetPtr = 0;
34563470
if(f_firstPacket) { // search for ID3 Header in the first packet
34573471
f_firstPacket = false;
@@ -3468,9 +3482,7 @@ void Audio::processWebStreamTS() {
34683482
}
34693483
}
34703484

3471-
if(!ts_parsePacket(&ts_packet[0], &ts_packetStart, &ts_packetLength)){
3472-
f_chunkFinished = true; // something went wrong
3473-
}
3485+
ts_parsePacket(&ts_packet[0], &ts_packetStart, &ts_packetLength); // todo: check for errors
34743486

34753487
if(ts_packetLength) {
34763488
size_t ws = InBuff.writeSpace();
@@ -3488,6 +3500,8 @@ void Audio::processWebStreamTS() {
34883500
if (byteCounter == m_contentlength || byteCounter == chunkSize) {
34893501
f_chunkFinished = true;
34903502
byteCounter = 0;
3503+
int av = _client->available();
3504+
if(av == 7) for(int i = 0; i < av; i++) _client->read(); // waste last chunksize: 0x0D 0x0A 0x30 0x0D 0x0A 0x0D 0x0A (==0, end of chunked data transfer)
34913505
}
34923506
if(m_contentlength && byteCounter > m_contentlength) {log_e("byteCounter overflow, byteCounter: %d, contentlength: %d", byteCounter, m_contentlength); return;}
34933507
if(chunkSize && byteCounter > chunkSize) {log_e("byteCounter overflow, byteCounter: %d, chunkSize: %d", byteCounter, chunkSize); return;}
@@ -3520,6 +3534,7 @@ void Audio::processWebStreamTS() {
35203534
AUDIO_INFO("buffer filled in %d ms", filltime);
35213535
}
35223536
}
3537+
35233538
return;
35243539
}
35253540
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

src/Audio.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*
55
* Created on: Oct 28,2018
66
*
7-
* Version 3.0.13z
8-
* Updated on: Dec 16.2024
7+
* Version 3.0.13zd
8+
* Updated on: Dec 30.2024
99
* Author: Wolle (schreibfaul1)
1010
*/
1111

@@ -382,6 +382,13 @@ void trim(char *str) {
382382
}
383383
return result;
384384
}
385+
386+
int32_t min3(int32_t a, int32_t b, int32_t c){
387+
uint32_t min_val = a;
388+
if (b < min_val) min_val = b;
389+
if (c < min_val) min_val = c;
390+
return min_val;
391+
}
385392
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
386393
// some other functions
387394
uint64_t bigEndian(uint8_t* base, uint8_t numBytes, uint8_t shiftLeft = 8) {

0 commit comments

Comments
 (0)