pschatzmann / arduino-audio-tools

Arduino Audio Tools (a powerful Audio library not only for Arduino)
GNU General Public License v3.0
1.43k stars 221 forks source link

player-url-i2s #24

Closed podaen closed 2 years ago

podaen commented 2 years ago

The player-url-i2s works for changing from one to next. After that it stays on the second channel. It is trying to change to next but for one reason it keeps taking the second url.

podaen commented 2 years ago

I know that it's a difficult one. What I know from that channel is that it changes from name in the weekends. Soo what we get is because of technical reasons.

podaen commented 2 years ago

I think you better set the timout back to 60sec because after a while it keeps changing from station to station without outputing audio anymore

W] AudioPlayer.h : 589 - -> timeout - moving to next stream

does this work with you? player.setCallbackMetadata(printMetaData); I don't get any data from it

pschatzmann commented 2 years ago

Just committed the correction to handle the case when we can a http failure return code. I think we can leave the timeout low after the latest change...

podaen commented 2 years ago

I tried to add some additional logic and decreased the max timeoutto 10 secs...

The time is much faster than 10sec... and sometimes it is 10sec.

pschatzmann commented 2 years ago

Feel free to increase the value in the sketch by calling the setTimeout() on the AudioSourceURL object...

podaen commented 2 years ago

here is the compete list. Normaly the all broadcasting. after 8 done it keeps returning timeout.

"http://19983.live.streamtheworld.com/QMUSIC.mp3", "http://22183.live.streamtheworld.com/JOE.mp3", "http://21303.live.streamtheworld.com/STUDIO_BRUSSEL_128.mp3", "http://icecast-servers.vrtcdn.be/stubru_tgs-high.mp3", "http://icecast-servers.vrtcdn.be/stubru_tijdloze-high.mp3", "http://icecast-servers.vrtcdn.be/ketnetradio-high.mp3", "http://22353.live.streamtheworld.com/MNM_128.mp3", "http://icecast-servers.vrtcdn.be/mnm_90s00s-high.mp3", "http://icecast-servers.vrtcdn.be/mnm_hits-high.mp3", "http://icecast-servers.vrtcdn.be/mnm_urb-high.mp3", "http://fred.torontocast.com:1050/stream", "http://icecast-servers.vrtcdn.be/radio1_classics_high.mp3", "http://icecast-servers.vrtcdn.be/radio2_benebene-high.mp3", "http://icecast-servers.vrtcdn.be/radio2_unwind-high.mp3", "http://icecast-servers.vrtcdn.be/stubru_bruut-high.mp3", "http://icecast-servers.vrtcdn.be/stubru_untz-high.mp3" "http://23553.live.streamtheworld.com:80/RADIO_2_VLAAMSBR_128.mp3", "http://randstad.wirelessbelgie.be:8330/stream.mp3", "https://22323.live.streamtheworld.com/TOPRETRO.mp3", "http://21253.live.streamtheworld.com/RADIO1_128.mp3",

pschatzmann commented 2 years ago

is this after my latest correction ?

pschatzmann commented 2 years ago

how about 15 or 20 seconds as default value ? I think 1 minute is too much...

podaen commented 2 years ago

I try now source.setTimeoutMs(15000);

podaen commented 2 years ago

I am on 20000ms and I am on url 19 and then it start again

E] HttpRequest.h : 181 - Connect failed Next Stream [W] HttpHeader.h : 225 - Waiting for data... [W] HttpRequest.h : 141 - no CONTENT_LENGTH found in reply [W] AudioPlayer.h : 589 - -> timeout - moving to next stream [W] HttpHeader.h : 225 - Waiting for data... [W] HttpRequest.h : 141 - no CONTENT_LENGTH found in reply [W] AudioPlayer.h : 589 - -> timeout - moving to next stream

podaen commented 2 years ago

These are all links where I had issues on before... only on the esp32. I just tested them all in the webbrowser on my pc and they all work.

//"http://23553.live.streamtheworld.com:80/RADIO_2_VLAAMSBR_128.mp3", //"http://randstad.wirelessbelgie.be:8330/stream.mp3", //"https://22323.live.streamtheworld.com/TOPRETRO.mp3", // THIS IS THE LINK WHERE IT STOPS WORKING NOW. //"http://streams.movemedia.eu:8000/zoefmmp3" //"http://21253.live.streamtheworld.com/RADIO1_128.mp3", //"https://22193.live.streamtheworld.com/OWR_DAB.mp3", //"http://eu2.radioboss.fm:8124/stream",

podaen commented 2 years ago

if I place this link below as first station and change evry 30sec form station and set the timeout on 20000ms than it plays sound but it is pitching sometimes. Like it can not follow the data and want to catchup. Or the data is comming in too slow.

https://22323.live.streamtheworld.com/TOPRETRO.mp3",

I also get this

libhelix - -> invalid frame size: -169 / max: 1600

podaen commented 2 years ago

I am not kidding, putting this link as first or placing it as almost last makes a difference.

pschatzmann commented 2 years ago

Hmm. I changed the default to 20000ms and moved the reset of the timeout after the next() so that the time of switching does not count...

podaen commented 2 years ago

That's the point. If you swich faster the problem doesn't occour anymore. But than you are following an other rout.

podaen commented 2 years ago

What do you prupose.... Update and test again?

pschatzmann commented 2 years ago

Maybe. If this does not help I think I will give up... Anyhow if you want to be on the save side you still have the possibility to use source.setTimeoutMs(60000); in your sketch...

podaen commented 2 years ago

We will see. It is sometimes beter to speed up. ;-)

podaen commented 2 years ago

Yes, it's working now with the latest version. I just test with all bad links and it doesn't keeps hanging in a loop and it doesn't jump over the next one.

And this one does not spond if it is not broadcasting.

http://mp3.streampower.be/sporza-high

Then I get a backtrace

Great! He is moving to the next one... Did you change anyting?

PS: All setting I used are still the same of the last time.

pschatzmann commented 2 years ago

Cool, I think I also found a solution for the last issue with the non returning URL. I added a timeout to the URLStream. If you think it is too long, you can adjust it with setUrlTimeout() in AudioSourceURL.

podaen commented 2 years ago

Are you recieving data from this?

player.setCallbackMetadata(printMetaData);

Is this the meta data of the url?

pschatzmann commented 2 years ago

No this is for ID3 Metadata which is part of the MP3 stream. If you want to access the parameters available in the http replay you can get them in the AudioSourceURL with actual_stream->httpRequest().reply().get("parameter-name")...

podaen commented 2 years ago

I will leave like that and set in the shetch. ERR_CONNECTION_TIMED_OUT is also 20sec on my browser.

pschatzmann commented 2 years ago

Cool

podaen commented 2 years ago

If you want to access the parameters available in the http replay you can get them in the AudioSourceURL with actual_stream->httpRequest().reply().get("parameter-name")...

Is it setting the tx power?

I found a topic about it on esp-idf https://esp32.com/viewtopic.php?t=5359

it is within the esp_wifi.h...

podaen commented 2 years ago

I get you now It is only for transmitting but I am recieving.

podaen commented 2 years ago

I tried

Serial.println(actual_stream->httpRequest().reply().get("NAME")); Serial.println(actual_stream->httpRequest().reply().get("PATH")); Serial.println(actual_stream->httpRequest().reply().get("TITLE")); Serial.println(actual_stream->httpRequest().reply().get("GET"));

But I can't get any information out of it. I don't know where to look for the parameter names

I set the audiologger to info and get this...

[I] HttpHeader.h : 218 - HttpHeader::read [W] HttpHeader.h : 225 - Waiting for data... [I] HttpHeader.h : 155 - HttpHeader::readLine -> HTTP/1.0 200 OK [I] HttpHeader.h : 443 - HttpReplyHeader::parse1stLine: HTTP/1.0 200 OK [I] HttpHeader.h : 155 - HttpHeader::readLine -> Expires: Thu, 01 Dec 2003 16:00:00 GMT [I] HttpHeader.h : 96 - HttpHeader::put -> 'Expires' : 'Thu, 01 Dec 2003 16:00:00 GMT' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Cache-Control: no-cache, must-revalidate [I] HttpHeader.h : 96 - HttpHeader::put -> 'Cache-Control' : 'no-cache, must-revalidate' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Pragma: no-cache [I] HttpHeader.h : 96 - HttpHeader::put -> 'Pragma' : 'no-cache' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Access-Control-Allow-Origin: [I] HttpHeader.h : 96 - HttpHeader::put -> 'Access-Control-Allow-Origin' : '' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Access-Control-Allow-Credentials: true [I] HttpHeader.h : 96 - HttpHeader::put -> 'Access-Control-Allow-Credentials' : 'true' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Set-Cookie: uuid=a9bac5a9-cca0-461d-9b26-ce9e3743ad95; expires=Sun, 05 Dec 2021 20:54:36 GMT; path=/; domain=.live.streamtheworld.com [I] HttpHeader.h : 96 - HttpHeader::put -> 'Set-Cookie' : 'uuid=a9bac5a9-cca0-461d-9b26-ce9e3743ad95; expires=Sun, 05 Dec 2021 20:54:36 GMT; path=/; domain=.live.streamtheworld.com' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Set-Cookie: uuid-s=a9bac5a9-cca0-461d-9b26-ce9e3743ad95; expires=Sun, 05 Dec 2021 20:54:36 GMT; path=/; domain=.live.streamtheworld.com [I] HttpHeader.h : 96 - HttpHeader::put -> 'Set-Cookie' : 'uuid-s=a9bac5a9-cca0-461d-9b26-ce9e3743ad95; expires=Sun, 05 Dec 2021 20:54:36 GMT; path=/; domain=.live.streamtheworld.com; [I] HttpHeader.h : 155 - HttpHeader::readLine -> Content-Type: audio/mpeg [I] HttpHeader.h : 96 - HttpHeader::put -> 'Content-Type' : 'audio/mpeg' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Connection: close [I] HttpHeader.h : 96 - HttpHeader::put -> 'Connection' : 'close' [I] HttpHeader.h : 155 - HttpHeader::readLine -> icy-name: [I] HttpHeader.h : 155 - HttpHeader::readLine -> icy-description: [I] HttpHeader.h : 155 - HttpHeader::readLine -> icy-url: https://joe.be/ [I] HttpHeader.h : 96 - HttpHeader::put -> 'icy-url' : 'https://joe.be/' [I] HttpHeader.h : 155 - HttpHeader::readLine -> icy-genre: Adult Contemporary [I] HttpHeader.h : 96 - HttpHeader::put -> 'icy-genre' : 'Adult Contemporary' [I] HttpHeader.h : 155 - HttpHeader::readLine -> icy-br: 128 [I] HttpHeader.h : 96 - HttpHeader::put -> 'icy-br' : '128' [I] HttpHeader.h : 155 - HttpHeader::readLine -> Server: MediaGateway 5.6.2-0391.el6 [I] HttpHeader.h : 96 - HttpHeader::put -> 'Server' : 'MediaGateway 5.6.2-0391.el6' [I] HttpHeader.h : 155 - HttpHeader::readLine ->

Not much information in the header that is usefull in my links. But this line pulls my intrest.

[I] Url.h : 112 - path->/JOE.mp3

pschatzmann commented 2 years ago

You can retrieve the header varables that are added with put:

pschatzmann commented 2 years ago

Can we close this issue related to navigation ? For any other topic please open a separate issue or I am starting to get lost...

podaen commented 2 years ago

Yeah, don't see any issue on the functionality of this example.

podaen commented 2 years ago

It would be nice if we could parse all resolved links of the https://de1.api.radio-browser.info/xml/stations/bycountrycodeexact/be in an url[]

pschatzmann commented 2 years ago

That's easy just use https://de1.api.radio-browser.info/csv/stations/bycountrycodeexact/be or https://de1.api.radio-browser.info/json/stations/bycountrycodeexact/be or json...

podaen commented 2 years ago

Yeah, json... the story of my life. It would be easy if I could save https://de1.api.radio-browser.info/csv/stations/bycountrycodeexact/be as an csv to my sd-card

pschatzmann commented 2 years ago

Just use a URLStream and copy the content to a File...

podaen commented 2 years ago

I'm avoiding the steams to write and pars the csv's to make a playlist of the sd card.

podaen commented 2 years ago

I have tested the url player with these external links.

"http://mp3.streampower.be/sporza-high",//nok
"https://22323.live.streamtheworld.com/TOPRETRO.mp3",//ok//nok on the second time it runs
"http://23553.live.streamtheworld.com:80/RADIO_2_VLAAMSBR_128.mp3",//ok
"http://20723.live.streamtheworld.com/QFOUTERADIO.mp3",//ok
"http://19983.live.streamtheworld.com/QMUSIC.mp3",//ok
"http://22183.live.streamtheworld.com/JOE.mp3",//ok
"http://21303.live.streamtheworld.com/STUDIO_BRUSSEL_128.mp3",//ok
"http://icecast-servers.vrtcdn.be/stubru_tgs-high.mp3",//ok
"http://icecast-servers.vrtcdn.be/stubru_tijdloze-high.mp3",//ok
"http://icecast-servers.vrtcdn.be/ketnetradio-high.mp3",//ok
"http://22353.live.streamtheworld.com/MNM_128.mp3",//ok
"http://icecast-servers.vrtcdn.be/mnm_90s00s-high.mp3",//ok
"http://icecast-servers.vrtcdn.be/mnm_hits-high.mp3",//ok
"http://icecast-servers.vrtcdn.be/mnm_urb-high.mp3",//ok
"http://fred.torontocast.com:1050/stream",//ok
"http://icecast-servers.vrtcdn.be/radio1_classics_high.mp3",//ok
"http://icecast-servers.vrtcdn.be/radio2_benebene-high.mp3",//ok
"http://icecast-servers.vrtcdn.be/radio2_unwind-high.mp3",//ok
"http://icecast-servers.vrtcdn.be/stubru_bruut-high.mp3",//ok
"http://icecast-servers.vrtcdn.be/stubru_untz-high.mp3",//ok
"http://23553.live.streamtheworld.com:80/RADIO_2_VLAAMSBR_128.mp3",//ok
"http://randstad.wirelessbelgie.be:8330/stream.mp3",//ok
"http://21253.live.streamtheworld.com/RADIO1_128.mp3",//ok

The all work but when I run over the second time it crashes on this link below, strange because it worked well on the first time.

"https://22323.live.streamtheworld.com/TOPRETRO.mp3",//ok//nok on the second time it runs

here is my stack description

Exception:Error:
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/list.c:214:::0x4008c2f5:uxListRemove
0x400014fd: ?? ??:0
0x4000150d: ?? ??:0
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c:3507:::0x4008adf2:vTaskDelete
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d1dc7:audio_tools
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d1e03:audio_tools
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d1d6b:audio_tools
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d20e9:audio_tools
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d2082:audio_tools
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d6203:NextStation()
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d625b:AutoNextStation()
E:\Documents\Visual Studio 2019\Projects\Arduino\player-url-i2s\player-url-i2s/player-url-i2s.ino(298): error 0x400d6269:loop()
C:\Users\Dave2Moon\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32/main.cpp(23): error 0x400de1ac:loopTask(void*)
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1):::0x400899c2:vPortTaskWrapper
0x40078000: ?? ??:0
0x40080400: ?? ??:0
0x400806a8: ?? ??:0

What do you think it could be... I have to say I reased the stack to 68000, because I have tested it for my esp32 with sd card in my shetch and that works.

podaen commented 2 years ago

many links are working but is it possible to support one of those

http://stream.zenfm.be/zenfm.mp3.m3u http://wma07.fluidstream.net:8080/fluid713.aac http://players.fluidstream.net/charleroi.pls http://www.opsinjoor.be/stream.php http://www.komilfoo.be/live/komilfoo.asx

pschatzmann commented 2 years ago

Most of these links are not working even if you open them in the browser. For the aac one you just need to use the Helix aac decoder instead of the mp3...

podaen commented 2 years ago

could they be merged in to one player?

pschatzmann commented 2 years ago

My decoder API is standardized. So all we would need is a combined decoder which determines the data format dynamically and forwards it to the correct implementation.

Are you interested to pick up the challenge ?

podaen commented 2 years ago

I am ready... You begin!

pschatzmann commented 2 years ago

I will not be able to work on this for the next couple of weeks. But I can give an outline what needs to be done with a couple of hints.

podaen commented 2 years ago

Most of these links are not working even if you open them in the browser.

Those links won't work with a brower, but with other software...

2021-12-13_132051

For example pls is a windows media player stream

MP3, AAC or OGG

are html5 supported

pschatzmann commented 2 years ago

Since this is Windows, it's not in my scope. Though it should not be too difficult to create AudioSource implementation which parses a pls file. It's just a text property file.

podaen commented 2 years ago

I m not interested too. My attention is now to the aac, m3u and mp3.

pschatzmann commented 2 years ago

I quickly double checked on github and did not find a single m3u parser in c or c++. The one in python had 2000 - 3000 lines of code. So that would be a couple of days of work....

update: we could build on vlc https://github.com/videolan/vlc/blob/master/modules/demux/playlist/m3u.c

podaen commented 2 years ago

I don't have much for now because I cann't get the data to work with. Normally for the AudioDecoder I have to give an AudioType in libhelix, but I cann't do that. So I looking for a way to read the bytes from the stream without losing them.

URLStream urlStream(wifi, password);
AudioSourceIcyUrl source(urlStream, urls, "audio/mp3");
I2SStream i2s;
VolumeOutput volume(i2s);
LogarithmicVolumeControl lvc(0.1);
MP3DecoderHelix decoder;
//DecoderHelix test(urlStream, urls, "audio/mp3");
DecoderHelix test(urlStream);
#if defined(USE_HELIX) || defined(USE_DECODERS)

#include "Stream.h"
#include "AudioTools/AudioTypes.h"
#include "AudioCodecs/CodecMP3Helix.h"
#include "AudioCodecs/CodecAACHelix.h"

enum AudioType {
    Undefined,
    MP3,
    AAC,
} content_type;

namespace audio_tools {

class DecoderHelix : public AudioDecoder {
    public:
        DecoderHelix() {
            LOGD(LOG_METHOD);
        }
        DecoderHelix(URLStream source) {
            LOGD(LOG_METHOD);
            source.readBytes(start, 3);//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        }
        ~DecoderHelix() {
                         content_type = Undefined;
        }
        virtual void setOutputStream(Print& outStream) {
        }
        void begin() {
            LOGD(LOG_METHOD);
            content_type = Undefined;
        }
        void end() {
            LOGD(LOG_METHOD);
        }
        MP3FrameInfo audioInfoEx() {
        }
        AudioBaseInfo audioInfo() {
        }
        size_t write(const void* mp3Data, size_t len) {
            LOGD("%s: %zu", LOG_METHOD, len);
            //if (start[0] == 0xFF && start[1] == 0xF1) {
            //  content_type = AAC;
            //  Serial.println("ACC");
            //}
            //else if (strncmp(start, "ID3", 3) || start[0] == 0xFF || start[0] == 0xFE) {
            //  content_type = MP3;
            //  Serial.println("MP3");
            //}
            //else if (strncmp(start, "RIFF", 4)) {
            // content_type = WAVE;
            //}
            //return content_type;
        }
        operator boolean() {
            return content_type != Undefined;
        }
        void setNotifyAudioChange(AudioBaseInfoDependent& bi) {
            LOGD(LOG_METHOD);
        }
    protected:
        uint8_t* start;
};
}
#endif
pschatzmann commented 2 years ago

I just committed a draft implementation. I did not have any time to test it though....

https://github.com/pschatzmann/arduino-audio-tools/blob/main/src/AudioCodecs/CodecHelix.h

podaen commented 2 years ago

I diden't test the aac decoder yet... This need to be resolved first before we can continue to a general decoder. I went ahead testing the aac decoder and this is where it stops.

assertion "res == pdTRUE" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/dport_access.c", line 187, function: esp_dport_access_int_init abort() was called at PC 0x400fed0b on core 0

podaen commented 2 years ago

it's a difficuld issue, do you have engough information or just no have the time to sort this out?