This commit is contained in:
Patrick Haßel 2025-06-06 12:58:18 +02:00
parent 1e304979c5
commit c81ca008cf
5 changed files with 48 additions and 48 deletions

View File

@ -43,7 +43,7 @@ bool running = false;
void audioStop() { void audioStop() {
if (running) { if (running) {
running = false; running = false;
Serial.println("[AUDIO ] STOP"); Serial.println("[AUDIO ] STOP");
} }
copyErrors = 0; copyErrors = 0;
copier.end(); copier.end();
@ -58,12 +58,12 @@ void audioStop() {
bool audioPlayInit(const Entry &entry) { bool audioPlayInit(const Entry &entry) {
audioStop(); audioStop();
Serial.printf("[AUDIO ] [%-4s] Start: %s\n", entry.type.c_str(), entry.url.c_str()); Serial.printf("[AUDIO ] [%-4s] Start: %s\n", entry.type.c_str(), entry.url.c_str());
running = true; running = true;
if (entry.type == "ICY" || entry.type == "SNAP") { if (entry.type == "ICY" || entry.type == "SNAP") {
if (!isWifiConnected()) { if (!isWifiConnected()) {
Serial.printf("[AUDIO ] [%-4s] WiFi not connected.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] WiFi not connected.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
@ -71,7 +71,7 @@ bool audioPlayInit(const Entry &entry) {
if (entry.type == "SD") { if (entry.type == "SD") {
if (!SD.begin(PIN_AUDIO_KIT_SD_CARD_CS)) { if (!SD.begin(PIN_AUDIO_KIT_SD_CARD_CS)) {
Serial.printf("[AUDIO ] [%-4s] Failed to mount SD-card.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to mount SD-card.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
@ -82,13 +82,13 @@ bool audioPlayInit(const Entry &entry) {
bool audioBeginMP3Stream(const Entry &entry, Stream &source) { bool audioBeginMP3Stream(const Entry &entry, Stream &source) {
if (!mp3Decoder.begin()) { if (!mp3Decoder.begin()) {
Serial.printf("[AUDIO ] [%-4s] Failed to start MP3DecoderHelix.", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to start MP3DecoderHelix.", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
if (!mp3Stream.begin()) { if (!mp3Stream.begin()) {
Serial.printf("[AUDIO ] [%-4s] Failed to start EncodedAudioStream.", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to start EncodedAudioStream.", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
@ -96,7 +96,7 @@ bool audioBeginMP3Stream(const Entry &entry, Stream &source) {
copier.begin(mp3Stream, source); copier.begin(mp3Stream, source);
if (copier.copy() == 0) { if (copier.copy() == 0) {
Serial.printf("[AUDIO ] [%-4s] Failed to copy initial data.", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to copy initial data.", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
@ -110,7 +110,7 @@ bool audioPlayICY(const Entry &entry) {
} }
if (!icy.begin(entry.url.c_str())) { if (!icy.begin(entry.url.c_str())) {
Serial.printf("[AUDIO ] [%-4s] Failed to start ICYStream.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to start ICYStream.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
@ -125,26 +125,26 @@ bool audioPlaySNAP(const Entry &entry) {
IPAddress ip; IPAddress ip;
if (!WiFiClass::hostByName(entry.url.c_str(), ip)) { if (!WiFiClass::hostByName(entry.url.c_str(), ip)) {
Serial.printf("[AUDIO ] [%-4s] Failed to resolve host.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to resolve host.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
snap.setServerIP(ip); snap.setServerIP(ip);
if (!snap.begin()) { if (!snap.begin()) {
Serial.printf("[AUDIO ] [%-4s] Failed to connect.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to connect.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
if (!opusDecoder.begin()) { if (!opusDecoder.begin()) {
Serial.printf("[AUDIO ] [%-4s] Failed to start OpusAudioDecoder.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to start OpusAudioDecoder.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
if (!snap.doLoop()) { if (!snap.doLoop()) {
Serial.printf("[AUDIO ] [%-4s] Failed to copy initial data.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to copy initial data.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
@ -158,14 +158,14 @@ bool audioPlaySD(const Entry &entry) {
} }
if (!SD.exists(entry.url.c_str())) { if (!SD.exists(entry.url.c_str())) {
Serial.printf("[AUDIO ] [%-4s] File not found.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] File not found.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
file = SD.open(entry.url.c_str(), FILE_READ); file = SD.open(entry.url.c_str(), FILE_READ);
if (!file) { if (!file) {
Serial.printf("[AUDIO ] [%-4s] Failed to open file.\n", entry.type.c_str()); Serial.printf("[AUDIO ] [%-4s] Failed to open file.\n", entry.type.c_str());
audioStop(); audioStop();
return false; return false;
} }
@ -187,25 +187,25 @@ bool audioPlay(const Entry &entry) {
if (entry.type == "SNAP") { if (entry.type == "SNAP") {
return audioPlaySNAP(entry); return audioPlaySNAP(entry);
} }
Serial.printf("[AUDIO ] Unknown type: %s\n", entry.type.c_str()); Serial.printf("[AUDIO ] Unknown type: %s\n", entry.type.c_str());
return false; return false;
} }
void audioSetup() { void audioSetup() {
AudioToolsLogger.setLogLevel(AudioToolsLogLevel::Error); AudioToolsLogger.setLogLevel(AudioToolsLogLevel::Error);
Serial.println("[AUDIO ] Initializing board..."); Serial.println("[AUDIO ] Initializing board...");
board.begin(); board.begin();
} }
bool audioLoop() { bool audioLoop() {
if (abs(board.volume() - audioVolume) >= 0.01f) { if (abs(board.volume() - audioVolume) >= 0.01f) {
Serial.printf("[AUDIO ] volume = %.2f\n", audioVolume); Serial.printf("[AUDIO ] volume = %.2f\n", audioVolume);
board.setVolume(audioVolume); board.setVolume(audioVolume);
stateBufferUpdateRequest(); stateBufferUpdateRequest();
} }
if (audioMute2 != audioMute) { if (audioMute2 != audioMute) {
audioMute2 = audioMute; audioMute2 = audioMute;
Serial.printf("[AUDIO ] mute = %s\n", audioMute ? "MUTED" : "no"); Serial.printf("[AUDIO ] mute = %s\n", audioMute ? "MUTED" : "no");
board.setMute(audioMute); board.setMute(audioMute);
stateBufferUpdateRequest(); stateBufferUpdateRequest();
} }
@ -218,7 +218,7 @@ bool audioLoop() {
if (copyErrors < 100) { if (copyErrors < 100) {
return true; return true;
} }
Serial.println("[AUDIO ] Stream ended!"); Serial.println("[AUDIO ] Stream ended!");
audioStop(); audioStop();
} }
return false; return false;

View File

@ -12,15 +12,15 @@ AsyncWebSocket ws("/ws");
void onWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, const AwsEventType type, void *arg, const uint8_t *data, const size_t len) { void onWebSocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, const AwsEventType type, void *arg, const uint8_t *data, const size_t len) {
if (type == WS_EVT_CONNECT) { if (type == WS_EVT_CONNECT) {
Serial.printf("[%-8s] Connected: %s\n", "WEBSOCKET", client->remoteIP().toString().c_str()); Serial.printf("[%-9s] Connected: %s\n", "WEBSOCKET", client->remoteIP().toString().c_str());
client->text(stateBuffer); client->text(stateBuffer);
} else if (type == WS_EVT_DISCONNECT) { } else if (type == WS_EVT_DISCONNECT) {
Serial.printf("[%-8s] Disconnected: %s\n", "WEBSOCKET", client->remoteIP().toString().c_str()); Serial.printf("[%-9s] Disconnected: %s\n", "WEBSOCKET", client->remoteIP().toString().c_str());
} }
} }
void httpSetup() { void httpSetup() {
Serial.println("[HTTP ] Starting HTTP server"); Serial.println("[HTTP ] Starting HTTP server");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
server.onNotFound([](AsyncWebServerRequest *request) { server.onNotFound([](AsyncWebServerRequest *request) {
const auto path = request->url(); const auto path = request->url();
@ -31,51 +31,51 @@ void httpSetup() {
} }
}); });
server.on("/state", [](AsyncWebServerRequest *request) { server.on("/state", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
request->send(200, "application/json", stateBuffer); request->send(200, "application/json", stateBuffer);
}); });
server.on("/stop", [](AsyncWebServerRequest *request) { server.on("/stop", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
playerState = PLAYER_STOP; playerState = PLAYER_STOP;
request->send(200); request->send(200);
}); });
server.on("/play", [](AsyncWebServerRequest *request) { server.on("/play", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
playerState = PLAYER_PLAY; playerState = PLAYER_PLAY;
request->send(200); request->send(200);
}); });
server.on("/pause", [](AsyncWebServerRequest *request) { server.on("/pause", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
playerState = PLAYER_PAUSE; playerState = PLAYER_PAUSE;
request->send(200); request->send(200);
}); });
server.on("/mute", [](AsyncWebServerRequest *request) { server.on("/mute", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
audioMute = true; audioMute = true;
request->send(200); request->send(200);
}); });
server.on("/unmute", [](AsyncWebServerRequest *request) { server.on("/unmute", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
audioMute = false; audioMute = false;
request->send(200); request->send(200);
}); });
server.on("/up", [](AsyncWebServerRequest *request) { server.on("/up", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
audioVolume = max(0.0f, min(audioVolume + 0.05f, 1.0f)); audioVolume = max(0.0f, min(audioVolume + 0.05f, 1.0f));
request->send(200); request->send(200);
}); });
server.on("/down", [](AsyncWebServerRequest *request) { server.on("/down", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
audioVolume = max(0.0f, min(audioVolume - 0.05f, 1.0f)); audioVolume = max(0.0f, min(audioVolume - 0.05f, 1.0f));
request->send(200); request->send(200);
}); });
server.on("/next", [](AsyncWebServerRequest *request) { server.on("/next", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
playerSkip += 1; playerSkip += 1;
request->send(200); request->send(200);
}); });
server.on("/back", [](AsyncWebServerRequest *request) { server.on("/back", [](AsyncWebServerRequest *request) {
Serial.println("[HTTP ] " + request->url()); Serial.println("[HTTP ] " + request->url());
playerSkip -= 1; playerSkip -= 1;
request->send(200); request->send(200);
}); });

View File

@ -69,7 +69,7 @@ void updateStateBufferIfNeeded() {
void playerStart(const Entry &entry) { void playerStart(const Entry &entry) {
if (entry.type == "") { if (entry.type == "") {
Serial.println("[PLAYER ] Not playing empty Entry => STOP"); Serial.println("[PLAYER ] Not playing empty Entry => STOP");
playerState = PLAYER_STOP; playerState = PLAYER_STOP;
} else if (audioPlay(entry)) { } else if (audioPlay(entry)) {
errorMs = 0; errorMs = 0;
@ -77,7 +77,7 @@ void playerStart(const Entry &entry) {
} else { } else {
errorMs = max(1UL, millis()); errorMs = max(1UL, millis());
delayMs = min(DELAY_MS_MAX, delayMs + DELAY_MS_ADD); delayMs = min(DELAY_MS_MAX, delayMs + DELAY_MS_ADD);
Serial.printf("[PLAYER ] Retry delay: %d ms\n", delayMs); Serial.printf("[PLAYER ] Retry delay: %d ms\n", delayMs);
} }
stateBufferUpdateRequest(); stateBufferUpdateRequest();
} }

View File

@ -20,7 +20,7 @@ size_t playlistIndex = 0;
std::vector<Entry> playlistEntries; std::vector<Entry> playlistEntries;
void playlistClear() { void playlistClear() {
Serial.println("[PLAYLIST] clear"); Serial.println("[PLAYLIST ] clear");
playlistTitle = ""; playlistTitle = "";
playlistIndex = 0; playlistIndex = 0;
playlistEntries.clear(); playlistEntries.clear();
@ -29,17 +29,17 @@ void playlistClear() {
void playlistAdd(String entry) { void playlistAdd(String entry) {
entry.trim(); entry.trim();
Serial.println("[PLAYLIST] [ADD] " + entry); Serial.println("[PLAYLIST ] [ADD] " + entry);
const auto index_type_url = entry.indexOf('|'); const auto index_type_url = entry.indexOf('|');
if (index_type_url < 0) { if (index_type_url < 0) {
Serial.println("[PLAYLIST] type/url-delimiter not found: " + entry); Serial.println("[PLAYLIST ] type/url-delimiter not found: " + entry);
return; return;
} }
auto type = entry.substring(0, index_type_url); auto type = entry.substring(0, index_type_url);
type.trim(); type.trim();
if (type != "TITLE" && type != "ICY" && type != "SD" && type != "SNAP") { if (type != "TITLE" && type != "ICY" && type != "SD" && type != "SNAP") {
Serial.println("[PLAYLIST] Unknown type: " + type); Serial.println("[PLAYLIST ] Unknown type: " + type);
} }
entry = entry.substring(index_type_url + 1); entry = entry.substring(index_type_url + 1);
@ -52,13 +52,13 @@ void playlistAdd(String entry) {
const auto index_url_title = entry.indexOf('|'); const auto index_url_title = entry.indexOf('|');
if (index_url_title < 0) { if (index_url_title < 0) {
Serial.println("[PLAYLIST] url/title-delimiter not found: " + entry); Serial.println("[PLAYLIST ] url/title-delimiter not found: " + entry);
return; return;
} }
auto url = entry.substring(0, index_url_title); auto url = entry.substring(0, index_url_title);
url.trim(); url.trim();
if (url.isEmpty()) { if (url.isEmpty()) {
Serial.println("[PLAYLIST] url is empty."); Serial.println("[PLAYLIST ] url is empty.");
return; return;
} }
@ -70,18 +70,18 @@ void playlistAdd(String entry) {
void playlistLoad(const String &path) { void playlistLoad(const String &path) {
playlistClear(); playlistClear();
Serial.println("[PLAYLIST] Loading playlist: " + path); Serial.println("[PLAYLIST ] Loading playlist: " + path);
if (!SD.begin(PIN_AUDIO_KIT_SD_CARD_CS)) { if (!SD.begin(PIN_AUDIO_KIT_SD_CARD_CS)) {
Serial.println("[PLAYLIST] Failed to initialize SD card."); Serial.println("[PLAYLIST ] Failed to initialize SD card.");
return; return;
} }
if (!SD.exists(path)) { if (!SD.exists(path)) {
Serial.println("[PLAYLIST] File not found."); Serial.println("[PLAYLIST ] File not found.");
return; return;
} }
auto file = SD.open(path, FILE_READ); auto file = SD.open(path, FILE_READ);
if (!file) { if (!file) {
Serial.println("[PLAYLIST] Failed to open file."); Serial.println("[PLAYLIST ] Failed to open file.");
} }
while (file.available() > 0) { while (file.available() > 0) {

View File

@ -12,21 +12,21 @@ void wifiLoop() {
if (connected) { if (connected) {
// still connected // still connected
} else { } else {
Serial.printf("[WIFI ] Disconnected!\n"); Serial.printf("[WIFI ] Disconnected!\n");
} }
} else { } else {
if (connected) { if (connected) {
wifiLastMillis = 0; wifiLastMillis = 0;
Serial.printf("[WIFI ] Connected: %s\n", WiFi.localIP().toString().c_str()); Serial.printf("[WIFI ] Connected: %s\n", WiFi.localIP().toString().c_str());
} else if (wifiLastMillis == 0 || millis() - wifiLastMillis > 10000) { } else if (wifiLastMillis == 0 || millis() - wifiLastMillis > 10000) {
WiFi.disconnect(); WiFi.disconnect();
yield(); yield();
if (wifiLastMillis != 0) { if (wifiLastMillis != 0) {
Serial.printf("[WIFI ] Connect timeout!\n"); Serial.printf("[WIFI ] Connect timeout!\n");
} }
wifiLastMillis = max(1UL, millis()); wifiLastMillis = max(1UL, millis());
const auto ssid = "HappyNet"; const auto ssid = "HappyNet";
Serial.printf("[WIFI ] Connecting: %s\n", ssid); Serial.printf("[WIFI ] Connecting: %s\n", ssid);
WiFi.begin(ssid, "1Grausame!Sackratte7"); WiFi.begin(ssid, "1Grausame!Sackratte7");
yield(); yield();
} else { } else {