IndexedDB: Blob und Array Buffer

Permalink

In meinem letzten Artikel habe ich versucht Dateien aus dem Internet mittels der Indexed Database API zu speichern. Dabei bin ich auf ein unerwartetes Problem im Browser Chrome gestoßen. Dieser verweigert nämlich das Speichern von BLOB-Objekten da sie vorgeblich nicht serialisiert werden können. Das ist sehr ärgerlich da sich diese Lösung unter Firefox und Internet Explorer als gut erwiesen hat.

Bevor ich mich an Alternativen wage hier noch einmal die bisherige Teilschritte in Kurzform:

  1. Durchführen eines Ajax-Requests der eine Datei in Form eines Array Buffers liefert
  2. Umwandeln dieses Array Buffers in ein BLOB
  3. Öffnen einer Datenbank
  4. Speichern des BLOB’s unter der URL der ursprünglichen Datei

Neuer Versuch …

Von Astro erhielt ich dankenswerterweise den Hinweis das Chrome beim speichern von Array Buffern nicht so empfindlich ist. Also habe ich das Vorgehen etwas umgestellt. Versuchsweise speicherte ich direkt den Array Buffer aus dem Ajax-Request. Die Umwandlung des Buffers fand dann beim öffnen der Datei statt.

Das umwandeln in ein BLOB ist übrigens zwingend erforderlich. Um nämlich die gespeicherte Datei später mit einem Audio-Tag wiedergeben zu können braucht sie eine URL. Diese kann man für lokale Objekte mittels der Funktion createObjectURL() erzeugen. Und eben diese Methode akzeptiert keine Array Buffer sondern BLOB’s.

… neue Probleme

Leider führt das neue Vorgehen wiederum zu zwei neuen Problemen die nervig bis untragbar sind:

Erstens ist das umwandeln größerer Buffer recht langsam. Dadurch kommt es beim abspielen einer in diesem Format gespeicherten Datei zu Verzögerungen von mehreren Sekunden. Das ist wirklich störend. Vor dem Umstellen des Codes viel diese Verzögerung gar nicht auf da sie gegenüber der Zeit zum Download der Datei vernachlässigbar ist. Nun tritt sie aber alleinstehend auf und verzögert die Wiedergabe ganz erheblich.

Das zweite Problem besteht darin das sowohl Chrome als auch Firefox und Opera (die letzteren zumindest unter Android) nicht sehr gut mit größeren Array Buffern zurechtkommen. Aufgefallen ist es bei MP3-Dateien mit einer Spielzeit von zwei Stunden und mehr. Chrome bricht den Speichervorgang mit einer Fehlermeldung ab die besagt das die maximale Größe einzelner Werte überschritten ist (The serialized value is too large). Firefox und Opera hingegen stürzt einfach ab und veranlasst in einer Vielzahl von Fällen Android zu einem Neustart. Die gleichen Dateien als BLOB gespeichert verursachen unter Firefox keine Probleme.

Eventuell kann man eine stabilere Lösung finden indem man den Array Buffer vor dem in kleinere Teile aufsplittet und diese dann speichert. Ich muss mir das aber noch mal durch den Kopf gehen lassen wenn ich etwas mehr Zeit habe.

Zurück zum Anfang

Ich will nicht ausschließen das gerade letzteres Problem bei Firefox gerätespezifisch (Samsung Galaxy S3 mini) ist, trotzdem habe ich mich dazu entschlossen zur ursprünglichen Version zurückzukehren. Unter Chrome kann man sich mit der File System API behelfen und unter Firefox sind BLOB’s in einer IndexedDB das Mittel der Wahl. Einen passenden Prototyp habe ich trotzdem erstellt um das Thema in Zukunft nachverfolgen zu können.