Ich baue derzeit grade meinen dritten espuino mit sd mmc und dem pn5180 und wundere mich wie ich das auswählen der titel ein wenig schneller machen kann. Wenn ich hingehe und zB ein Hörbuch mit 200 tracks wähle, wird ja so wie ich das verstanden habe eine Liste angelegt in der die Titel nicht mehr als Titel gespeichert werden (was ja recht groß wäre) sondern als numerische Zahl (1-200).
Leider dauert es dennoch teilweise 20 Sekunden bis der zuletzt gespielte track wieder läuft. Kann ich etwas tun um das zu beschleunigen?
Zb die Tracks umbennenen? Wenn ja wird das über den ID3 Tag gemacht oder den titel?
Es ist so, dass zum Erstellen der Playlist der gesamte Inhalt von einem Verzeichnis angezeigt werden muss. Das ist ein Vorgang, der leider nicht fürchterlich schnell ist, ich wüsste jedoch auch nicht, wie ich ihn beschleunigen sollte. Da ist die Regel einfach: Je mehr Dateien ein Verzeichnis hat, desto länger dauert es.
Wenn du jetzt eine Playlist pausierst und befindest dich im Modus Hörspiel, dann wird die Stelle der Pause gespeichert. Dabei wird jedoch nicht der Dateiname gespeichert sondern die Nummer des Titels innerhalb der Playlist. Also sagen wir mal du hast 200 Titel und du drückst jetzt bei 16 Pause, dann speichert der ne 16 und innerhalb der 16 auch noch eine Position in Bytes.
Jetzt hörst du irgendwas Anderes und willst jetzt wieder in dein altes Hörspiel wieder einsteigen. Dann muss dennoch die Playlist wieder neu generiert werden. Einerseits, damit du weißt, was Titel 16 überhaupt ist. Und andererseits, weil du 17, 18, 19… ja auch hören willst. D.h. das Parsing ist genau das Gleiche, wie auch beim ersten Mal. Der Unterschied ist nur, dass der Startpunkt ein anderer ist.
TL;DR: Schneller wird es nur, wenn man wenige Titel nimmt. Ich habe für den Sohnemann mehrere Pipi-Langstrumpf-Folgen, die teilweise mehrere Stunden gehen. Die splitte ich (aus Faulheit) alle zehn Minuten. Das ist dann ok finde ich.
Wieviel Aufwand ist es zum Implementieren, dass die Playlist auf die SD-Karte geschrieben wird? Dann ist das nächste abspielen deutlich schneller. Als Nachteil wird sie nicht aktualisiert wenn der Benutzer neue Dateien hinzufügt. In diesem Fall ist aber auch die Abspielposition kaputt.
Wenn jetzt der Browser zum Upload der Datei genutzt wird, dann könnte auch dieser direkt die Playlist anpassen und korrigieren. Im Refactoring ist es ja gerade ein Thema. Vielleicht könnte man das dort mit berücksichtigen?
Diesen Ansatz hatten wir bereits.
Probleme:
a) Es ist ziemlich lästig, ne ganze SD zu parsen. Also das dauert ne ganze Weile, wenn da viel drauf ist. Ja, das macht man nicht dauernd. Aber du willst auch nicht minutenlang warten, wenn du mal eben ne neue Karten anlernen willst.
b) Wenn man die Daten komplett liefert, so dass man daraus einen JSTree macht, dann können das ziemlich viele Daten werden. Das graphisch aufzubauen war irgendwie nicht so performat. Holst du in der GUI ad hoc nur genau den Kram, den du brauchst, dann hat sich das als besser herausgestellt (hätte ich auch nicht erwartet aber es ist so).
Es hat sich dann gezeigt, dass es besser ist, den Verzeichnisinhalt dynamisch nachzuladen. Also wir hatten da vor einer Weile mal ein json-File, in dem der ganze Inhalt lag. Also genau Pre-Caching, wie du es dir vorstellst.
Also ich spreche jetzt nur für die GUI. Pre-Caching für die Playlist-Generierung hatten wir noch nicht. Das würde das Problem mit dem langsamen Parsen sicher beheben, ja. Aber ich denke skalieren würde das auch wieder nicht. Weil dann hast du ein großes JSON-File und wenn du das in ArduinoJson steckst, dann brauchst wieder Heap, den du ggf nicht hast.
Erstmal eine Verständnisfrage:
Es geht hier doch um das verzögerte Abspielen eines Hörspiels nach dem Auflegen einer Karte. Die WebUI ist an der Stelle nicht beteiligt?
Ich rede vom Rückgabewert von returnPlaylistFromSD(…). Wenn du diese Liste auf der SD-Karte hättest, kannst du schnell starten. Wenn sie nicht existiert, dann musst du sie erstellen wie bisher.
Das ist ja nur der Inhalt des Ordners und dieser verändert sich im Vergleich zu einer SD-Karte nicht so oft.
Und in der WebUI ist der Verzeichnisinhalt irgendwann ja auch vollständig da. Solange muss das Skript welches dann diese Playlist aktualisiert eben warten bevor sie diese aktualisieren kann. Wobei mir auffällt, dass ich über FTP nicht nachgedacht habe sondern nur den Upload über die UI.
Ja. Ich habe jetzt im Prinzip unpassenderweise die GUI ins Spiel gebracht, das hat mit dem Playlist-Generator erstmal nix zu tun. Aber das Problem ist ja das Gleiche: Du willst nicht so lange warten, bis der Verzeichnisinhalt ausgeparst ist. Also musst du es irgendwann mal komplett parsen, in einer Datei ablegen und dann, bei Bedarf, auslesen.
Für GUI hatten wir das Pre-Caching wie gesagt schon. Es war ok, aber dynamisch hat sich das als praktikabler erwiesen. Bei der Playlist-Generierung wird es ähnlich sein: Es löst ein Problem, aber wirft neue auf.
Was grundsätzlich denkbar wäre: Man legt so ein Caching-File pro Ordner an. Und zwar nicht als json, sondern einfach als csv. Weil das kann man ziemlich einfach ohne Overhead parsen und in eine Playlist stecken. So läuft aktuell die Playlist-Generierung auch schon. Nur mit dem Unterschied, dass die csv-Struktur im Speicher liegt.
Und es braucht eine Funktion, die durch die ganze SD-Karte durchiteriert und diese Files schreibt. Per Compile-Direktive kann der Benutzer steuern, ob er das gerne dynamisch oder pre-cached hätte. Oder alternativ/zusätzlich: Man schaut im Verzeichnis x nach, ob man eine solche Datei findet. Wenn ja, dann liest man sie aus. Wenn nein, dann macht man das dynamisch (wie jetzt) und schreibt zusätzlich eine solche Datei.
Wäre vermutlich machbar und würde auch skalieren denke ich. Aber das Generieren der Files kann recht lange dauern bei vielen Files.
Parsen? Einfach als Block laden und die ‚;‘ durch ‚\0‘ ersetzen und damit die Pointer anpassen
Der Punkt „alternativ/zusätzlich“ sollte alleine schon ausreichen um es zu implementieren. Dann spart man sich das Iterieren über die gesamte SD-Karte.
Es bleibt aber der Nachteil mit dem Aktualisieren.
*Wenn die SD-Karte entfernt und geändert wird, mussen die Playlisten händisch gelöscht werden
*In der WebUI kann die Playliste beim Upload der Datei automatisch angepasst werden
*Beim FTP sehe ich leider keine Möglichkeit eines Hooks, ansonsten kann man dort bei einer übertragenen Datei in dem Ordner die Playliste löschen. Dann wird sie beim Start wieder aktualisiert.
Wenn man dir bei der Umsetzung helfen kann, gib bitte Bescheid.
Natürlich Parsen. Aus dem CSV muss ein 2d-Array gebaut werden. Aber wie gesagt, ein CSV habe ich jetzt auch schon beim Auslesen des Verzeichnisinhalts. Alternativ käme hier dann halt die Option der Datei ins Spiel. Und ist die Datei nicht da, dann kann ich sie mit dem Inhalt, den ich eh als CSV im Speicher habe, einfach schreiben.
Also ja, ich denke der Aufwand ist nicht so groß. Klingt nach einem Plan
Ließe sich das evtl. über den Zeitpunkt der letzten Aktualisierung des Ordners lösen? Also: Playlist-Cache ist outdated und muss neu generieren werden, wenn er a) nicht existiert oder b) der changed timestamp des Caches kleiner ist als der des Ordners.
Somit forcieren wir, dass bei jeder Änderung am Ordner auch die Playlist neu generiert wird. Das kann falsch positiv ausgelöst werden, aber so oft fasst man die SD ja nicht an?
Oder habe ich da etwas übersehen?
Ist grundsätzlich denkbar. Wir haben jedoch drei Anwendungsfälle:
a) Files werden per Computer auf die SD-Karte kopiert.
Hier kann ich vermutlich hingehen und den Cache einfach auf den gleichen Timestamp setzen wie den Ordner. Welcher Timestamp das im Detail genau ist, ist eigentlich gar nicht so wichtig.
b) Files werden per Webtransfer auf die SD-Karte kopiert.
Hier könnte man dafür sorgen, dass bei Dateioperationen in einem Verzeichnis automatisch der Filecache gelöscht wird. Beim nächsten Mal wieder er dann automatisch wieder erstellt. @Christian / @Harry : Was meint ihr dazu?
c) Files werden per FTP kopiert
Hier müsste man wohl ähnlich verfahren wie bei (b).
Was man glaube ich eher vermeiden will, das ist der Einsatz von NTP, um die aktuelle Uhrzeit zu kriegen. Weil man kann sich einfach nicht drauf verlassen, dass der ESPuino auch wirklich Internet-Zugang hat. Ggf. kann man da auch in unschöne Timeouts laufen.
Ja, das ist sicher eine gute Idee und ich würde auch einfach Löschen und dann ggf. neu anlegen. Keine Timestamps vergleichen.
Man könnte auch über das Webinterface den Cache „on demand“ erstellen lassen.
…und bevor man in den Deepsleep geht, noch einmal prüfen, ob irgendwo ein Index-Cache fehlt…Da die Box dann ja vermutlich eh gerade nicht benutzt wird.
Für die Zufallswiedergabe hilft das ja nicht, oder?
Genau. Macht da keinen Sinn. @Christian Hättest du zufällig Zeit/Lust, das automatische Löschen zur GUI hinzuzufügen? In Js breche ich mir wieder einen ab
Grundsätzlich gerne. Ich würde das aber im ESP machen, wenn dort die Dateioperation durchgeführt wird. @Harry hatte damals extra bestimmte Aktionen wieder zurück in den ESP Code gelegt.
Ich könnte was machen um den Refresh per GUI anstoßen zu können?!