You can now also play MP3s streamed from the internet. (Very rough & wonky code. More or less proof-of-concept right now.)

This commit is contained in:
2019-11-20 06:13:15 +01:00
parent 94489618ca
commit b989784fb9
5 changed files with 96 additions and 6 deletions

View File

@ -9,6 +9,7 @@ size_t SDDataSource::position() { return _file.position(); }
void SDDataSource::seek(size_t position) { _file.seek(position); }
size_t SDDataSource::size() { return _file.size(); }
void SDDataSource::close() { _file.close(); }
bool SDDataSource::usable() { return _file; }
void SDDataSource::skip_id3_tag() {
uint32_t original_position = _file.position();
@ -33,3 +34,61 @@ void SDDataSource::skip_id3_tag() {
_file.seek(original_position);
}
}
////////////// HTTPSDataSource //////////////
HTTPSDataSource::HTTPSDataSource(String url, uint32_t offset) {
uint8_t tries_left = 5;
int status;
do {
if (tries_left == 0) {
ERROR("Redirection loop? Cancelling!\n");
return;
}
tries_left--;
DEBUG("Connecting to %s...\n", url.c_str());
if (_http) delete _http;
_http = new HTTPClient();
const char* headers[] = {"location"};
_http->collectHeaders(headers, 1);
bool result = _http->begin(url);
DEBUG("HTTP->begin result: %d\n", result);
if (!result) return;
status = _http->GET();
DEBUG("Status code: %d\n", status);
if (status == HTTP_CODE_FOUND || status==HTTP_CODE_MOVED_PERMANENTLY || status==HTTP_CODE_TEMPORARY_REDIRECT) {
if (_http->hasHeader("Location")) {
url = _http->header("Location");
} else if (_http->hasHeader("location")) {
url = _http->header("location");
} else {
ERROR("Got redirection HTTP code, but could not find Location header.\n");
for(int i=0; i<_http->headers(); i++) {
DEBUG(" Header: %s=%s\n", _http->headerName(i).c_str(), _http->header(i).c_str());
}
return;
}
} else if (status != HTTP_CODE_OK) {
DEBUG("Unexpected HTTP return code. Cancelling.\n");
return;
}
} while (status != HTTP_CODE_OK);
_length = _http->getSize();
DEBUG("Content-Length: %d\n", _length);
_stream = _http->getStreamPtr();
}
HTTPSDataSource::~HTTPSDataSource() {
if (_stream) _stream->stop();
_http->end();
delete _stream;
delete _http;
}
bool HTTPSDataSource::usable() { return _http && _stream; }
size_t HTTPSDataSource::read(uint8_t* buf, size_t len) { size_t result = _stream->read(buf, len); _position += result; return result; }
uint8_t HTTPSDataSource::read() { _position++; return _stream->read(); }
size_t HTTPSDataSource::position() { return _position; }
void HTTPSDataSource::seek(size_t position) { return; /* TODO */ }
size_t HTTPSDataSource::size() { return _length; }
void HTTPSDataSource::close() { _stream->stop(); }

View File

@ -545,10 +545,16 @@ bool Player::play() {
void Player::_play_file(String file, uint32_t file_offset) {
INFO("play_file('%s', %d)\n", file.c_str(), file_offset);
_spi->select_sd();
_file = new SDDataSource(file);
if (file.startsWith("/")) {
_file = new SDDataSource(file);
} else if (file.startsWith("https://")) {
_file = new HTTPSDataSource(file);
} else {
return;
}
_file_size = _file->size();
_spi->select_sd(false);
if (!_file) {
if (!_file || !_file->usable()) {
DEBUG("Could not open file %s", file.c_str());
return;
}

View File

@ -5,7 +5,11 @@
#include <algorithm>
#include <ArduinoJson.h>
Playlist::Playlist(String path) {
Playlist::Playlist(String path, bool is_url) {
if (is_url) {
_files.push_back(path);
return;
}
// Add files to _files
SPIMaster::select_sd();
TRACE("Examining folder %s...\n", path.c_str());