9 #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE 10 #include "esp_crt_bundle.h" 16 static const uint32_t READ_WRITE_TIMEOUT_MS = 20;
19 static const uint32_t ERROR_COUNT_NO_DATA_READ_TIMEOUT = 100;
21 static const size_t HTTP_STREAM_BUFFER_SIZE = 2048;
23 static const uint8_t MAX_REDIRECTION = 5;
67 return ESP_ERR_INVALID_STATE;
87 return ESP_ERR_INVALID_ARG;
90 esp_http_client_config_t client_config = {};
92 client_config.url = uri.c_str();
93 client_config.cert_pem =
nullptr;
94 client_config.disable_auto_redirect =
false;
95 client_config.max_redirection_count = 10;
97 client_config.user_data =
this;
98 client_config.buffer_size = HTTP_STREAM_BUFFER_SIZE;
99 client_config.keep_alive_enable =
true;
100 client_config.timeout_ms = 5000;
102 #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE 103 if (uri.find(
"https:") != std::string::npos) {
104 client_config.crt_bundle_attach = esp_crt_bundle_attach;
108 this->
client_ = esp_http_client_init(&client_config);
110 if (this->
client_ ==
nullptr) {
114 esp_err_t err = esp_http_client_open(this->
client_, 0);
121 int64_t header_length = esp_http_client_fetch_headers(this->
client_);
122 if (header_length < 0) {
127 int status_code = esp_http_client_get_status_code(this->
client_);
134 ssize_t redirect_count = 0;
136 while ((esp_http_client_set_redirection(this->
client_) == ESP_OK) && (redirect_count < MAX_REDIRECTION)) {
137 err = esp_http_client_open(this->
client_, 0);
143 header_length = esp_http_client_fetch_headers(this->
client_);
144 if (header_length < 0) {
149 status_code = esp_http_client_get_status_code(this->
client_);
162 err = esp_http_client_get_url(this->
client_, url, 500);
173 #ifdef USE_AUDIO_MP3_SUPPORT 178 #ifdef USE_AUDIO_FLAC_SUPPORT 186 return ESP_ERR_NOT_SUPPORTED;
196 return ESP_ERR_NO_MEM;
203 if (this->
client_ !=
nullptr) {
213 #ifdef USE_AUDIO_MP3_SUPPORT 214 if (strcasecmp(content_type,
"mp3") == 0 || strcasecmp(content_type,
"audio/mp3") == 0 ||
215 strcasecmp(content_type,
"audio/mpeg") == 0) {
219 if (strcasecmp(content_type,
"audio/wav") == 0) {
222 #ifdef USE_AUDIO_FLAC_SUPPORT 223 if (strcasecmp(content_type,
"audio/flac") == 0 || strcasecmp(content_type,
"audio/x-flac") == 0) {
234 switch (evt->event_id) {
235 case HTTP_EVENT_ON_HEADER:
236 if (strcasecmp(evt->header_key,
"Content-Type") == 0) {
248 if (remaining_bytes > 0) {
250 pdMS_TO_TICKS(READ_WRITE_TIMEOUT_MS));
262 if (esp_http_client_is_complete_data_received(this->
client_)) {
272 if (received_len > 0) {
276 }
else if (received_len < 0) {
281 if (bytes_to_read > 0) {
289 delay(READ_WRITE_TIMEOUT_MS);
298 if (this->
client_ !=
nullptr) {
299 esp_http_client_close(this->
client_);
300 esp_http_client_cleanup(this->
client_);
std::unique_ptr< AudioSinkTransferBuffer > output_transfer_buffer_
static std::unique_ptr< AudioSinkTransferBuffer > create(size_t buffer_size)
Creates a new sink transfer buffer.
AudioFileType audio_file_type_
void cleanup_connection_()
uint32_t no_data_read_count_
std::string str_lower_case(const std::string &str)
Convert the string to lower case.
AudioReaderState file_read_()
esp_err_t add_sink(const std::weak_ptr< RingBuffer > &output_ring_buffer)
Adds a sink ring buffer for audio data.
const uint8_t * file_current_
bool str_endswith(const std::string &str, const std::string &end)
Check whether a string ends with a value.
AudioReaderState read()
Reads new file data from the source and sends to the ring buffer sink.
esp_err_t start(const std::string &uri, AudioFileType &file_type)
Starts reading an audio file from an http source.
static AudioFileType get_audio_type(const char *content_type)
Determines the audio file type from the http header's Content-Type key.
std::shared_ptr< RingBuffer > file_ring_buffer_
Implementation of SPI Controller mode.
static esp_err_t http_event_handler(esp_http_client_event_t *evt)
Monitors the http client events to attempt determining the file type from the Content-Type header...
esp_http_client_handle_t client_
AudioReaderState http_read_()
AudioFile * current_audio_file_
void IRAM_ATTR HOT delay(uint32_t ms)