baldram / ESP_VS1053_Library

A library for VS1053 MP3 Codec Breakout adapted for Espressif ESP8266 and ESP32 boards.
https://platformio.org/lib/show/1744/ESP_VS1053_Library
GNU General Public License v3.0
112 stars 37 forks source link

Defining host and path are not clear #92

Closed jackjean88 closed 2 years ago

jackjean88 commented 2 years ago

Hi, I have successfully coded the set ESP32 VS2053 using the WebRadioDemo example. Since I am looking for listening french radios, I was surprised by the poor quality of this stream : http://icecast.radiofrance.fr/franceinter-midfi.mp3 (noisy and mashed). Others streams sound really good like thisone : http://stream.rfm.fr/rfm-wr7.mp3 So I decided to find another host for Radio France and found thisone : http://direct.franceinter.fr/live/franceinter-midfi.mp3

Here starts my problem : this last link contains 2 x "/" So I first choose to set the host at "direct.franceinter.fr" and the path at "/live/franceinter-midfi.mp3" Result no connection. Than I set the host at "direct.franceinter.fr/live" and the path at "/live/franceinter-midfi.mp3" Same result : no connection. My question is : how to set both host and path for url containing more than one "/" ? Thank you in advance for your lightening.

philippedc commented 2 years ago

Hi jackjean, here there is another one who listen to French radio stations 👍

1- you cannot code directly the url http://direct.franceinter.fr/live/franceinter-midfi.mp3 because this url redirects to http://icecast.radiofrance.fr/franceinter-midfi.mp3 and the webradio exemple cannot treat redirect url As I also like to listen to African web radios, most of them use several redirect url. So, I've found a workaround way to follow redirect urls, because it is possible to detect redirect url as their header returns the code 302:

if( client.connect(urlStation, portStation.toInt()) ) {
  client.print(String("GET ") + pathStation + " HTTP/1.0\r\n" +
              "Host: " + urlStation + "\r\n" + 
              "Connection: close\r\n\r\n");
  counter = 0;
}  // end of client.connect test

} // end of !client.connected() test

if( client.available() && !pause ) {

// recherche si l'url contient une redirection temporaire type 302
// il peut y avoir des redirections multiples
if( headerSearch ) {
  headerSearch = false;
  String header = client.readStringUntil('\n');   // read the header until \n
  while( header.indexOf("HTTP/1.0 302" ) >= 0) {  // tant qu'il y a l'entĂȘte d'une redirection
    Serial.print(++boucle); Serial.print("-"); Serial.print(++ligne); Serial.print("=>|"); Serial.println(header);
    while((header.indexOf("Location:") < 0) && (header.indexOf("location:") < 0)) {  // recherche la ligne d'url de redirection
      header = client.readStringUntil('\n');
      Serial.print(boucle); Serial.print("-"); Serial.print(++ligne); Serial.print("=>|"); Serial.println(header);
    }

// récupération des champs séparés par des "/" dans la donnée brut
    String newPortStation = "80";
    String newUrlStation  = "";
    String newPathStation = "/";
    if( header[14] == 's' ) newPortStation = "443";
    byte index = 0;
    while( header[index] != '/' ) index ++;
    index +=2;
    while( header[index] != '/' ) {
      newUrlStation += header[index];
      index ++;
    }
    index ++;
    for( byte k=index ; k < header.length() ; k++ ) newPathStation += header[k];

    Serial.print("récupération des champs de données = ");
    Serial.print(newUrlStation); Serial.print(" + "); Serial.println(newPathStation);
    if( client.connect(newUrlStation, newPortStation.toInt()) ) {
      client.print(String("GET ") + newPathStation + " HTTP/1.0\r\n" +
              "Host: " + urlStation + "\r\n" + 
              "Connection: close\r\n\r\n");
    }  // end of client.connect test
    header = client.readStringUntil('\n');  // read the header until \n 
  }    // end of while on header
  boucle = 0;
  ligne = 0;
}      // end of test on headerSearch

client.read(mp3buff, buffSize);
yield();
player.playChunk(mp3buff, buffSize);

} // end of client.available test } // fin de loop

2- As I tried http://direct.franceinter.fr/live/franceinter-midfi.mp3 and this url redirect to http://icecast.radiofrance.fr/franceinter-midfi.mp3, you should get the same bad quality sound. There is also the url http://icecast.radiofrance.fr:/franceinter-lofi.mp3 in lower sound quality, but you may get a better result. Why are these stations so noisy ? Because there are many 'no sound data' in the stream, and they make glitches in the sound.

If you read several threads many people here tried workarrounds with complex ring buffers, etc... to suppress glitches. No success for me. However I can listen my web radio as long as I wish since the day the radio station is requested in http 1.0 instead of http 1.1, look at the 'client.print()' in the above code lines.

Dr-Dawg commented 2 years ago

I'd like to add a few things :-)

The number of slashes "/" doesen't matter, but they have to be in path, not in host. I.e. your first idea would have worked if it wasn't for the redirect.

For finding stations, I found the following urls quite helpfull: http://radio.garden and http://fmstream.org For the latter one you can for example find that there's even a 192 MBit stream for France Inter: http://icecast.radiofrance.fr/franceinter-hifi.aac (as far as I remember VS1053 is capable of playing aac streams).

Like @philippedc said, meta data (like songtitle etc.) in the stream can cause glitches when send to VS1053. the way meta data is delivered depends on the radio station, for most cases you can switch meta data on and off by adding a line

"Icy-MetaData: 0\r\n" +

or

"Icy-MetaData: 1\r\n" +

to the client.print command (right before the Connection: close line).

For so called chunked encoding (see #52) data comes in chunks, you can either try to filter it out searching for /r and /n in the stream, like @wmarkow in the Web radio chunked demo https://github.com/baldram/ESP_VS1053_Library/pull/48 or, the easier way, like @philippedc said, use HTTP/1.0 instead of HTTP/1.1, since HTTP/1.0 does not support chunk encoding.

Buffering the stream proves to be heplful for streams that go around the globe and do not provide a stable connection.

jackjean88 commented 2 years ago

@philippedc Grand merci pour le support ! Le passage au http 1.0 a résolu tous mes soucis (ou presque). Je suis passé au aac en 192 Kbps sur la majorité de mes url! Le dernier souci de chunks à été réglé par la solution de DrDawg en ajoutant la ligne de leur inhibition . Tout roule !! Super assistance, rapide, efficace, bref des vrais pros !!!

jackjean88 commented 2 years ago

@Dr-Dawg As confirmed to philippedc, in 2 post you have both solved all my troubles!!! You are awarded for the solution to disable the chunks, last ennoying point. I am now enjoying the webradio as I wanted. Great thanks to you !!!

Dr-Dawg commented 2 years ago

De rien :-)

baldram commented 2 years ago

As confirmed to philippedc, in 2 post you have both solved all my troubles!!!

@jackjean88 Can we close the issue?

Btw. closed issues are great documentation for problem-solution approach! Regarding hints from @Dr-Dawg, I'm wondering whether to add some bonus chapter in README.md with radio stations finding-helpers 😄

philippedc commented 2 years ago

For finding stations, I found the following urls quite helpfull: http://radio.garden/ and http://fmstream.org/

@Dr-Dawg many thanks !

A good exercise for me tonight... to success to listen this radio: http://radioseribatu.out.airtime:8000/radioseribatu_a (Balinese music)