diff --git a/README.md b/README.md index afa1da4..68b2a15 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ I started this project back in october 2019 and never expected it to become that * Partition-layout for ESP32 is changed along with this branch. This step was necessary in order to resize (enlarge) the memory-region where especially the assignments for the RFID-tags are saved. As all permanent settings (e.g. WiFi-settings) are saved there too, it's necessary to re-enter WiFi-credentials after update. But the most important thing is to recover the assignments for the RFID-tags. Please consult my [migration-document](https://forum.espuino.de/t/wechsel-zum-refactoring-branch-was-ist-zu-beachten/510). ## Changelog Last three events: -* 20.07.2021: Adding new playmode: multiple webradio-paylist from local .m3u-file +* 23.07.2021: Adding new playmode: from local .m3u-file (files or webstreams) * 13.07.2021: Adding OTA-support via webGUI * 09.07.2021: Making branch `refactoring` the new master ## Known bugs @@ -278,7 +278,7 @@ It's not just simply playing music; different playmodes are supported: * `folder/playlist (alph. sorted)` => plays all tracks in alph. order from a folder forever * `folder/playlist (random order)` => plays all tracks in random order from a folder forever * `webradio` => always only one "track": plays a webstream -* `Webradiolist from local .m3u-File` => can be one or more webradio-stations with local .m3u as sourcefile +* `list (files from SD and/or webstreams) from local .m3u-File` => can be one or more files / webradio-stations with local .m3u as sourcefile ### Modification RFID-tags There are special RFID-tags, that don't start music by themself but can modify things. If applied a second time, it's previous action/modification will be reversed. Please note: all sleep-modes do dimming (Neopixel) automatically because it's supposed to be used in the evening when going to bed. Well, at least that's my children's indication :-) So first make sure to start the music then use a modification-card in order to apply your desired modification: diff --git a/changelog.md b/changelog.md index 6fd32ca..148125c 100644 --- a/changelog.md +++ b/changelog.md @@ -9,7 +9,7 @@ * 09.07.2021: Making branch `refactoring` the the master * 09.07.2021: Making master the new branch `old` (not maintained any longer!) * 13.07.2021: Adding OTA-support via webGUI -* 20.07.2021: Adding new playmode: multiple webradio-paylist from local .m3u-file +* 23.07.2021: Adding new playmode: from local .m3u-file (files or webstreams) ## Old (monolithic main.cpp) * 11.07.2020: Added support for reversed Neopixel addressing. diff --git a/html/management_DE.html b/html/management_DE.html index 0756a9d..cce23d6 100644 --- a/html/management_DE.html +++ b/html/management_DE.html @@ -272,7 +272,7 @@ - +
diff --git a/html/management_EN.html b/html/management_EN.html index 3404b64..b5b173f 100644 --- a/html/management_EN.html +++ b/html/management_EN.html @@ -272,7 +272,7 @@ - +
diff --git a/src/AudioPlayer.cpp b/src/AudioPlayer.cpp index 3e0a342..9ae5064 100644 --- a/src/AudioPlayer.cpp +++ b/src/AudioPlayer.cpp @@ -553,10 +553,18 @@ void AudioPlayer_Task(void *parameter) { } } - if (gPlayProperties.playMode == WEBSTREAM || gPlayProperties.playMode == WEBSTREAMS_LOCAL_M3U) { // Webstream - audio->connecttohost(*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber)); - gPlayProperties.playlistFinished = false; + if (!strncmp("http", *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber), 4)) { + gPlayProperties.isWebstream = true; } else { + gPlayProperties.isWebstream = false; + } + gPlayProperties.currentRelPos = 0; + audioReturnCode = false; + + if (gPlayProperties.playMode == WEBSTREAM || (gPlayProperties.playMode == LOCAL_M3U && gPlayProperties.isWebstream)) { // Webstream + audioReturnCode = audio->connecttohost(*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber)); + gPlayProperties.playlistFinished = false; + } else if (gPlayProperties.playMode != WEBSTREAM && !gPlayProperties.isWebstream) { // Files from SD if (!gFSystem.exists(*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber))) { // Check first if file/folder exists snprintf(Log_Buffer, Log_BufferLength, "%s: %s", (char *) FPSTR(dirOrFileDoesNotExist), *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber)); @@ -566,31 +574,37 @@ void AudioPlayer_Task(void *parameter) { } else { audioReturnCode = audio->connecttoFS(gFSystem, *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber)); // consider track as finished, when audio lib call was not successful - if (!audioReturnCode) { - System_IndicateError(); - gPlayProperties.trackFinished = true; - continue; - } + } + } + + if (!audioReturnCode) { + System_IndicateError(); + gPlayProperties.trackFinished = true; + continue; + } else { + if (gPlayProperties.currentTrackNumber) { Led_Indicate(LedIndicatorType::PlaylistProgress); - if (gPlayProperties.startAtFilePos > 0) { - audio->setFilePos(gPlayProperties.startAtFilePos); - gPlayProperties.startAtFilePos = 0; - snprintf(Log_Buffer, Log_BufferLength, "%s %u", (char *) FPSTR(trackStartatPos), audio->getFilePos()); - Log_Println(Log_Buffer, LOGLEVEL_NOTICE); - } + } + if (gPlayProperties.startAtFilePos > 0) { + audio->setFilePos(gPlayProperties.startAtFilePos); + gPlayProperties.startAtFilePos = 0; + snprintf(Log_Buffer, Log_BufferLength, "%s %u", (char *) FPSTR(trackStartatPos), audio->getFilePos()); + Log_Println(Log_Buffer, LOGLEVEL_NOTICE); + } + if (!gPlayProperties.isWebstream) { // Is done via audio_showstation() char buf[255]; snprintf(buf, sizeof(buf) / sizeof(buf[0]), "(%d/%d) %s", (gPlayProperties.currentTrackNumber + 1), gPlayProperties.numberOfTracks, (const char *)*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber)); #ifdef MQTT_ENABLE publishMqtt((char *) FPSTR(topicTrackState), buf, false); #endif - #if (LANGUAGE == DE) - snprintf(Log_Buffer, Log_BufferLength, "'%s' wird abgespielt (%d von %d)", *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber), (gPlayProperties.currentTrackNumber + 1), gPlayProperties.numberOfTracks); - #else - snprintf(Log_Buffer, Log_BufferLength, "'%s' is being played (%d of %d)", *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber), (gPlayProperties.currentTrackNumber + 1), gPlayProperties.numberOfTracks); - #endif - Log_Println(Log_Buffer, LOGLEVEL_NOTICE); - gPlayProperties.playlistFinished = false; } + #if (LANGUAGE == DE) + snprintf(Log_Buffer, Log_BufferLength, "'%s' wird abgespielt (%d von %d)", *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber), (gPlayProperties.currentTrackNumber + 1), gPlayProperties.numberOfTracks); + #else + snprintf(Log_Buffer, Log_BufferLength, "'%s' is being played (%d of %d)", *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber), (gPlayProperties.currentTrackNumber + 1), gPlayProperties.numberOfTracks); + #endif + Log_Println(Log_Buffer, LOGLEVEL_NOTICE); + gPlayProperties.playlistFinished = false; } } @@ -599,20 +613,22 @@ void AudioPlayer_Task(void *parameter) { if (gPlayProperties.seekmode == SEEK_FORWARDS) { if (audio->setTimeOffset(jumpOffset)) { #if (LANGUAGE == DE) - Serial.printf("%d Sekunden nach vorne gesprungen\n", jumpOffset); + snprintf(Log_Buffer, Log_BufferLength, "%d Sekunden nach vorne gesprungen", jumpOffset); #else - Serial.printf("Jumped %d seconds forwards\n", jumpOffset); + snprintf(Log_Buffer, Log_BufferLength, "Jumped %d seconds forwards", jumpOffset); #endif + Log_Println(Log_Buffer, LOGLEVEL_NOTICE); } else { System_IndicateError(); } } else if (gPlayProperties.seekmode == SEEK_BACKWARDS) { if (audio->setTimeOffset(-(jumpOffset))) { #if (LANGUAGE == DE) - Serial.printf("%d Sekunden zurueck gesprungen\n", jumpOffset); + snprintf(Log_Buffer, Log_BufferLength, "%d Sekunden zurueck gesprungen", jumpOffset); #else - Serial.printf("Jumped %d seconds backwards\n", jumpOffset); + snprintf(Log_Buffer, Log_BufferLength, "Jumped %d seconds backwards", jumpOffset); #endif + Log_Println(Log_Buffer, LOGLEVEL_NOTICE); } else { System_IndicateError(); } @@ -634,7 +650,7 @@ void AudioPlayer_Task(void *parameter) { } // Calculate relative position in file (for neopixel) for SD-card-mode - if (!gPlayProperties.playlistFinished && gPlayProperties.playMode != WEBSTREAM) { + if (!gPlayProperties.playlistFinished && !gPlayProperties.isWebstream) { double fp = (double)audio->getFilePos() / (double)audio->getFileSize(); if (millis() % 100 == 0) { gPlayProperties.currentRelPos = fp * 100; @@ -866,7 +882,7 @@ void AudioPlayer_TrackQueueDispatcher(const char *_itemToPlay, const uint32_t _l break; } - case WEBSTREAMS_LOCAL_M3U: { // This is always just one "track" + case LOCAL_M3U: { // Can be one or more webradio-station(s) Log_Println((char *) FPSTR(modeWebstreamM3u), LOGLEVEL_NOTICE); if (Wlan_IsConnected()) { xQueueSend(gTrackQueue, &(musicFiles), 0); diff --git a/src/AudioPlayer.h b/src/AudioPlayer.h index f50b950..a3a0622 100644 --- a/src/AudioPlayer.h +++ b/src/AudioPlayer.h @@ -20,6 +20,7 @@ typedef struct { // Bit field uint8_t seekmode: 2; // If seekmode is active and if yes: forward or backwards? bool newPlayMono: 1; // true if mono; false if stereo (helper) bool currentPlayMono: 1; // true if mono; false if stereo + bool isWebstream: 1; // Indicates if track currenty played is a webstream } playProps; extern playProps gPlayProperties; diff --git a/src/HTMLmanagement_DE.h b/src/HTMLmanagement_DE.h index 393ac5c..6c87aee 100644 --- a/src/HTMLmanagement_DE.h +++ b/src/HTMLmanagement_DE.h @@ -272,7 +272,7 @@ static const char management_HTML[] PROGMEM = "\ \ \ \ - \ + \ \
\
\ diff --git a/src/HTMLmanagement_EN.h b/src/HTMLmanagement_EN.h index 140e198..a13edd7 100644 --- a/src/HTMLmanagement_EN.h +++ b/src/HTMLmanagement_EN.h @@ -272,7 +272,7 @@ static const char management_HTML[] PROGMEM = "\ \ \ \ - \ + \ \
\
\ diff --git a/src/Led.cpp b/src/Led.cpp index c373db8..a0c6f5f 100644 --- a/src/Led.cpp +++ b/src/Led.cpp @@ -467,7 +467,7 @@ static void Led_Task(void *parameter) { redrawProgress = true; } - if (gPlayProperties.playMode != WEBSTREAM && gPlayProperties.playMode != WEBSTREAMS_LOCAL_M3U) { + if (!gPlayProperties.isWebstream) { if (gPlayProperties.currentRelPos != lastPos || redrawProgress) { redrawProgress = false; lastPos = gPlayProperties.currentRelPos; diff --git a/src/SdCard.cpp b/src/SdCard.cpp index 6c19c16..c252735 100644 --- a/src/SdCard.cpp +++ b/src/SdCard.cpp @@ -154,7 +154,7 @@ char **SdCard_ReturnPlaylist(const char *fileName, const uint32_t _playMode) { } // Parse m3u-playlist and create linear-playlist out of it - if (_playMode == WEBSTREAMS_LOCAL_M3U) { + if (_playMode == LOCAL_M3U) { if (fileOrDirectory && !fileOrDirectory.isDirectory() && fileOrDirectory.size() >= 0) { enablePlaylistFromM3u = true; uint16_t allocCount = 1; @@ -170,7 +170,7 @@ char **SdCard_ReturnPlaylist(const char *fileName, const uint32_t _playMode) { return files; } char buf; - char lastBuf = '0'; + char lastBuf = '#'; uint32_t fPos = 1; serializedPlaylist[0] = '#'; diff --git a/src/Wlan.cpp b/src/Wlan.cpp index e7382c6..9af8f60 100644 --- a/src/Wlan.cpp +++ b/src/Wlan.cpp @@ -164,7 +164,7 @@ void writeWifiStatusToNVS(bool wifiStatus) { if (!wifiStatus) { if (gPrefsSettings.putUInt("enableWifi", 0)) { // disable Log_Println((char *) FPSTR(wifiDisabledAfterRestart), LOGLEVEL_NOTICE); - if (gPlayProperties.playMode == WEBSTREAM || gPlayProperties.playMode == WEBSTREAMS_LOCAL_M3U) { + if (gPlayProperties.isWebstream) { AudioPlayer_TrackControlToQueueSender(STOP); } delay(300); diff --git a/src/revision.h b/src/revision.h index f6e3d55..62e7caf 100644 --- a/src/revision.h +++ b/src/revision.h @@ -1,4 +1,4 @@ #ifndef __REVISION_H__ #define __REVISION_H__ - constexpr const char softwareRevision[] PROGMEM = "Software-revision: 20210720-2"; + constexpr const char softwareRevision[] PROGMEM = "Software-revision: 20210723-1"; #endif \ No newline at end of file diff --git a/src/values.h b/src/values.h index bb84985..9eeaa86 100644 --- a/src/values.h +++ b/src/values.h @@ -25,7 +25,7 @@ #define ALL_TRACKS_OF_DIR_SORTED_LOOP 7 // Play all files of a directory (alph. sorted) in infinite-loop #define ALL_TRACKS_OF_DIR_RANDOM_LOOP 9 // Play all files of a directory (randomized) in infinite-loop #define WEBSTREAM 8 // Play webradio-stream - #define WEBSTREAMS_LOCAL_M3U 11 // Plays webreadio-streams with addresses from a local m3u-file + #define LOCAL_M3U 11 // Plays items (webstream or files) with addresses/paths from a local m3u-file #define BUSY 10 // Used if playlist is created