diff --git a/html/management_DE.html b/html/management_DE.html
index c39f820d..7eb8acac 100644
--- a/html/management_DE.html
+++ b/html/management_DE.html
@@ -824,7 +824,7 @@
if(data.dir) {
type = "folder";
- } else if ((/\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|flac|FLAC)$/i).test(data.name)) {
+ } else if ((/\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|m4a|M4A|flac|FLAC)$/i).test(data.name)) {
type = "audio";
} else {
type = "file";
@@ -904,7 +904,14 @@
items.play = {
label: "Abspielen",
action: function(x) {
- var playMode = node.data.directory?"5":"1";
+ var playMode = 1;
+ if (node.data.directory) {
+ playMode = 5;
+ } else {
+ if ((/\.(m3u|M3U)$/i).test(node.data.path)) {
+ playMode = 11;
+ }
+ }
postData("/exploreraudio?path=" + node.data.path + "&playmode=" + playMode);
}
};
diff --git a/src/AudioPlayer.cpp b/src/AudioPlayer.cpp
index f336b653..49681ea0 100644
--- a/src/AudioPlayer.cpp
+++ b/src/AudioPlayer.cpp
@@ -101,7 +101,7 @@ void AudioPlayer_Init(void) {
AudioPlayer_SetupVolume();
// delete cover image
- gFSystem.remove("/.cover");
+ gPlayProperties.coverFileName = NULL;
if (System_GetOperationMode() == OPMODE_NORMAL) { // Don't start audio-task in BT-mode!
xTaskCreatePinnedToCore(
AudioPlayer_Task, /* Function to implement the task */
@@ -363,10 +363,10 @@ void AudioPlayer_Task(void *parameter) {
if (gPlayProperties.title) {
free(gPlayProperties.title);
gPlayProperties.title = NULL;
- }
+ }
Web_SendWebsocketData(0, 30);
// delete cover image
- gFSystem.remove("/.cover");
+ gPlayProperties.coverFileName = NULL;
Web_SendWebsocketData(0, 40);
continue;
@@ -458,9 +458,9 @@ void AudioPlayer_Task(void *parameter) {
if (gPlayProperties.title) {
free(gPlayProperties.title);
gPlayProperties.title = NULL;
- }
+ }
// delete cover image
- gFSystem.remove("/.cover");
+ gPlayProperties.coverFileName = NULL;
Web_SendWebsocketData(0, 40);
audioReturnCode = audio->connecttoFS(gFSystem, *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber));
// consider track as finished, when audio lib call was not successful
@@ -598,9 +598,9 @@ void AudioPlayer_Task(void *parameter) {
if (gPlayProperties.title) {
free(gPlayProperties.title);
gPlayProperties.title = NULL;
- }
+ }
// delete cover image
- gFSystem.remove("/.cover");
+ gPlayProperties.coverFileName = NULL;
Web_SendWebsocketData(0, 40);
audioReturnCode = audio->connecttohost(*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber));
gPlayProperties.playlistFinished = false;
@@ -617,9 +617,9 @@ void AudioPlayer_Task(void *parameter) {
if (gPlayProperties.title) {
free(gPlayProperties.title);
gPlayProperties.title = NULL;
- }
+ }
// delete cover image
- gFSystem.remove("/.cover");
+ gPlayProperties.coverFileName = NULL;
Web_SendWebsocketData(0, 40);
audioReturnCode = audio->connecttoFS(gFSystem, *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber));
// consider track as finished, when audio lib call was not successful
@@ -1104,11 +1104,11 @@ void audio_id3data(const char *info) { //id3 metadata
// copy title
if (!gPlayProperties.title) {
gPlayProperties.title = (char *) x_malloc(sizeof(char) * 255);
- }
+ }
strncpy(gPlayProperties.title, info + 6, 255);
// notify web ui
Web_SendWebsocketData(0, 30);
- }
+ }
}
void audio_eof_mp3(const char *info) { //end of file
@@ -1170,19 +1170,11 @@ void audio_lasthost(const char *info) { //stream URL played
}
// id3 tag: save cover image
-void audio_id3image(File& file, const size_t pos, const size_t size) {
-
- // save raw image data to file "/.cover"
- snprintf(Log_Buffer, Log_BufferLength, "save album cover image: \"%s\"", (char *) file.name());
- Log_Println(Log_Buffer, LOGLEVEL_INFO);
- file.seek(pos);
- File coverFile = gFSystem.open("/.cover", FILE_WRITE);
- uint8_t buf[255];
- while(file.position() < (pos + size)) {
- int bytesRead = file.read(buf, sizeof(buf));
- coverFile.write( buf, bytesRead);
- }
- coverFile.close();
+void audio_id3image(File& file, const size_t pos, const size_t size) {
+ // save cover image file and position/size for later use
+ gPlayProperties.coverFileName = (char *)(file.name());
+ gPlayProperties.coverFilePos = pos;
+ gPlayProperties.coverFileSize = size;
// websocket notify cover image has changed
Web_SendWebsocketData(0, 40);
}
diff --git a/src/AudioPlayer.h b/src/AudioPlayer.h
index c10a5e93..63c97a4c 100644
--- a/src/AudioPlayer.h
+++ b/src/AudioPlayer.h
@@ -25,6 +25,9 @@ typedef struct { // Bit field
bool tellIpAddress: 1; // If true current IP-address is spoken
bool currentSpeechActive: 1; // If speech-play is active
bool lastSpeechActive: 1; // If speech-play was active
+ char *coverFileName; // current coverfile
+ size_t coverFilePos; // current cover file position
+ size_t coverFileSize; // current cover file size
} playProps;
extern playProps gPlayProperties;
diff --git a/src/HTMLmanagement_DE.h b/src/HTMLmanagement_DE.h
index b7454ff8..6d57c498 100644
--- a/src/HTMLmanagement_DE.h
+++ b/src/HTMLmanagement_DE.h
@@ -824,7 +824,7 @@ static const char management_HTML[] PROGMEM = " \
\
if(data.dir) {\
type = \"folder\";\
- } else if ((/\\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|flac|FLAC)$/i).test(data.name)) {\
+ } else if ((/\\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|m4a|M4A|flac|FLAC)$/i).test(data.name)) {\
type = \"audio\";\
} else {\
type = \"file\";\
@@ -904,7 +904,14 @@ static const char management_HTML[] PROGMEM = " \
items.play = {\
label: \"Abspielen\",\
action: function(x) {\
- var playMode = node.data.directory?\"5\":\"1\";\
+ var playMode = 1;\
+ if (node.data.directory) {\
+ playMode = 5; \
+ } else {\
+ if ((/\\.(m3u|M3U)$/i).test(node.data.path)) {\
+ playMode = 11;\
+ }\
+ } \
postData(\"/exploreraudio?path=\" + node.data.path + \"&playmode=\" + playMode);\
}\
};\
diff --git a/src/Web.cpp b/src/Web.cpp
index 7a239f05..c63f2b1d 100644
--- a/src/Web.cpp
+++ b/src/Web.cpp
@@ -577,8 +577,13 @@ void Web_SendWebsocketData(uint32_t client, uint8_t code) {
entry["volume"] = AudioPlayer_GetCurrentVolume();
if (gPlayProperties.title) {
// show current audio title from id3 metadata
+ if (gPlayProperties.numberOfTracks > 1) {
+ snprintf(Log_Buffer, Log_BufferLength, "(%u / %u): %s", gPlayProperties.currentTrackNumber+1, gPlayProperties.numberOfTracks, gPlayProperties.title);
+ } else {
+ snprintf(Log_Buffer, Log_BufferLength, "%s", gPlayProperties.title);
+ };
char utf8Buffer[200];
- convertAsciiToUtf8(gPlayProperties.title, utf8Buffer);
+ convertAsciiToUtf8(Log_Buffer, utf8Buffer);
entry["name"] = utf8Buffer;
} else if (gPlayProperties.playMode == NO_PLAYLIST) {
// no active playlist
@@ -1135,10 +1140,10 @@ bool Web_DumpNvsToSd(const char *_namespace, const char *_destFile) {
// handle album cover image request
static void handleCoverImageRequest(AsyncWebServerRequest *request) {
- if (!gFSystem.exists("/.cover")) {
+ if (!gPlayProperties.coverFileName) {
// empty image:
// request->send(200, "image/svg+xml", "