Streaming und Caching mit Supabase
Erzeugen und streamen Sie Sprache über Supabase Edge Functions. Speichern Sie Sprache in Supabase Storage und cachen Sie Antworten über das integrierte CDN.
Anleitung · Setzt voraus, dass Sie den ElevenAPI- Schnellstart abgeschlossen haben und über ein Supabase-Konto verfügen.
Einführung
In dieser Anleitung erfahren Sie, wie Sie mit Supabase Edge Functions, Supabase Storage und ElevenLabs eine Edge-API erstellen, um Sprache zu generieren, zu streamen, zu speichern und zwischenzuspeichern.
Voraussetzungen
- Ein ElevenLabs-Konto mit einem API-Schlüssel.
- Ein Supabase-Konto (Sie können sich über database.new kostenlos registrieren).
- Die auf Ihrem Rechner installierte Supabase CLI.
- Die auf Ihrem Rechner installierte Deno-Runtime sowie optional die Einrichtung in Ihrer bevorzugten IDE.
Einrichtung
Ein Supabase-Projekt lokal erstellen
Führen Sie nach der Installation der Supabase CLI den folgenden Befehl aus, um lokal ein neues Supabase-Projekt zu erstellen:
Storage-Bucket konfigurieren
Sie können die Supabase CLI so konfigurieren, dass automatisch ein Storage-Bucket erstellt wird. Fügen Sie dazu diese Konfiguration in der Datei config.toml hinzu:
Wenn Sie supabase start ausführen, wird in Ihrem lokalen Supabase-
Projekt ein neuer Storage-Bucket erstellt. Wenn Sie diesen in Ihr gehostetes Supabase-Projekt übertragen möchten, können Sie supabase seed buckets --linked ausführen.
Hintergrundaufgaben für Supabase Edge Functions konfigurieren
Um bei der lokalen Entwicklung Hintergrundaufgaben in Supabase Edge Functions zu nutzen, müssen Sie die folgende Konfiguration in der Datei config.toml hinzufügen:
Bei Verwendung der Richtlinie per_worker wird die Function bei Änderungen nicht automatisch neu geladen. Sie müssen sie
manuell neu starten, indem Sie supabase functions serve ausführen.
Eine Supabase Edge Function für die Sprachgenerierung erstellen
Erstellen Sie mit folgendem Befehl eine neue Edge Function:
Wenn Sie VS Code oder Cursor verwenden, wählen Sie y, wenn die CLI fragt: “Generate VS Code settings for Deno? [y/N]”.
Umgebungsvariablen einrichten
Erstellen Sie im Verzeichnis supabase/functions eine neue Datei .env und fügen Sie die folgenden Variablen hinzu:
Abhängigkeiten
Das Projekt verwendet einige Abhängigkeiten:
- Die Bibliothek @supabase/supabase-js für die Interaktion mit der Supabase-Datenbank.
- Das ElevenLabs-JavaScript SDK für die Interaktion mit der Text-to-Speech-API.
- Das Open-Source-Paket object-hash, um aus den Anfrageparametern einen Hash zu generieren.
Da Supabase Edge Functions die Deno-Runtime verwenden, müssen Sie die Abhängigkeiten nicht installieren. Sie können sie über das Präfix npm: importieren.
Supabase Edge Function programmieren
Fügen Sie in Ihrer neu erstellten Datei supabase/functions/text-to-speech/index.ts den folgenden Code hinzu:
Detaillierte Code-Erklärung
Einige Aspekte des Codes sind besonders wichtig. Sehen wir sie uns Schritt für Schritt an.
Eingehende Anfrage verarbeiten
Verwenden Sie zum Verarbeiten der eingehenden Anfrage den Handler Deno.serve. In der Demo validieren wir den Anfrageursprung nicht. Sie können beispielsweise den Anfrageursprung validieren oder ein Benutzer-Zugriffstoken anhängen und es mit Supabase Auth validieren.
Aus der eingehenden Anfrage extrahiert die Function die Parameter text und voiceId. Der Parameter voiceId ist optional und verwendet standardmäßig die ElevenLabs-ID für die Stimme „Allison“.
Mit der Bibliothek object-hash generiert die Function aus den Anfrageparametern einen Hash. Dieser Hash wird verwendet, um in Supabase Storage nach vorhandenen Audiodateien zu suchen.
In Supabase Storage nach vorhandenen Audiodateien suchen
Supabase Storage verfügt über ein integriertes Smart CDN, mit dem Sie Ihre Dateien einfach zwischenspeichern und bereitstellen können.
Hier sucht die Function in Supabase Storage nach einer vorhandenen Audiodatei. Falls die Datei existiert, gibt die Function sie aus Supabase Storage zurück.
Sprache als Stream generieren und in zwei Zweige aufteilen
Mit den Streaming-Funktionen der ElevenLabs API generiert die Function einen Stream. Der Vorteil: Auch bei längeren Texten können Sie das Audio sofort an Ihre Nutzer streamen und den Stream anschließend im Hintergrund in Supabase Storage hochladen.
Das ermöglicht die bestmögliche Nutzererfahrung, sodass sich selbst große Textblöcke erstaunlich schnell anfühlen. Dies geschieht in Zeile 17, wo die Methode stream.tee() den ReadableStream in zwei Zweige aufteilt: einen für den Browser und einen für Supabase Storage.
Audiostream im Hintergrund in Supabase Storage hochladen
Die Methode EdgeRuntime.waitUntil in Zeile 20 des vorherigen Schritts lädt den Audiostream mit der Function uploadAudioToStorage im Hintergrund in Supabase Storage hoch. Dadurch kann die Function die Streaming-Antwort sofort an den Browser zurückgeben, während das Audio in Supabase Storage hochgeladen wird.
Sobald das Storage-Objekt erstellt wurde, gibt die Function die Audiodatei beim nächsten Aufruf Ihrer Nutzer mit denselben Parametern über das Supabase-Storage-CDN zurück.
Lokal ausführen
Um die Function lokal auszuführen, führen Sie folgende Befehle aus:
Sobald der lokale Supabase-Stack läuft, starten Sie die Function mit folgendem Befehl und beobachten die Logs:
Ausprobieren
Rufen Sie http://127.0.0.1:54321/functions/v1/text-to-speech?text=hello%20world auf, um die Function in Aktion zu hören.
Rufen Sie anschließend http://127.0.0.1:54323/project/default/storage/buckets/audio auf, um die Audiodatei in Ihrem lokalen Supabase-Storage-Bucket zu sehen.
Bei Supabase bereitstellen
Falls noch nicht geschehen, erstellen Sie unter database.new ein neues Supabase-Konto und verknüpfen Sie das lokale Projekt mit Ihrem Supabase-Konto:
Führen Sie anschließend folgenden Befehl aus, um die Function bereitzustellen:
Secrets der Function festlegen
Nachdem Sie alle Secrets lokal festgelegt haben, können Sie mit folgendem Befehl die Secrets in Ihrem Supabase-Projekt setzen:
Function testen
Die Function ist so konzipiert, dass sie direkt als Quelle für ein <audio>-Element verwendet werden kann.