mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 00:56:16 +00:00
Adds text-to-speech that synthesizes higher-quality audio (Google Cloud
TTS) and plays it on a speaker via the /speaker endpoint. Because Cloud
TTS returns audio bytes (not a fetchable URL), the service caches the
clip and hosts it at GET /media/tts/{id}, mirroring the "ding" endpoint,
then points the speaker at that local URL.
The design is a pluggable Provider interface (pkg/service/tts) wrapping
two modes:
- translate: hands the speaker the (undocumented) Google Translate URL
directly (no credentials), reusing models.BuildTranslateTTSURL.
- google-cloud: REST API key auth (no SDK/gRPC), bytes cached locally.
Surfaces:
- service: POST /mgmt/tts/speak, GET /mgmt/tts/config, GET /media/tts/{id};
configured via TTS_PROVIDER / TTS_GOOGLE_API_KEY / TTS_LANGUAGE /
TTS_VOICE / TTS_APP_KEY / TTS_VOLUME.
- CLI: `soundtouch-cli tts speak` (calls the service with mgmt Basic Auth).
- web: a "TTS" source view (like Play URL / TuneIn), proxied to the
service via /api/device-speak/{id}.
The /speaker app_key requirement and model limitations still apply; see
docs/content/docs/reference/SPEAKER-ENDPOINT.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
50 lines
1.9 KiB
Go
50 lines
1.9 KiB
Go
// Package tts turns text into speaker-playable audio for the local service.
|
|
//
|
|
// SoundTouch speakers play a notification by fetching a URL themselves (via the
|
|
// /speaker endpoint). Two delivery shapes exist behind a single Provider
|
|
// interface:
|
|
//
|
|
// - Direct-URL providers (e.g. Google Translate) hand the speaker a URL it
|
|
// fetches directly. No local hosting needed; Result.DirectURL is set.
|
|
// - Synthesizing providers (e.g. Google Cloud TTS) return audio *bytes*. The
|
|
// Service caches them and serves them from a local /media/tts/{id} URL that
|
|
// the speaker can reach. Result.Audio is set.
|
|
//
|
|
// The Service (service.go) hides this distinction: callers ask it to Prepare a
|
|
// Request and get back a single playable URL.
|
|
package tts
|
|
|
|
import "context"
|
|
|
|
// Audio format identifiers for a Request.
|
|
const (
|
|
FormatMP3 = "mp3"
|
|
FormatWAV = "wav"
|
|
)
|
|
|
|
// Request describes one synthesis. Language and Voice are provider-specific:
|
|
// the Translate provider expects a short code like "EN"; Google Cloud expects a
|
|
// BCP-47 tag like "en-US" plus an optional voice name. The active provider is
|
|
// fixed per deployment, so the configured defaults are matched to it.
|
|
type Request struct {
|
|
Text string
|
|
Language string
|
|
Voice string
|
|
Format string // FormatMP3 (default) or FormatWAV
|
|
}
|
|
|
|
// Result is what a Provider returns. Exactly one of DirectURL or Audio is set.
|
|
type Result struct {
|
|
Audio []byte // synthesized bytes; nil for direct-URL providers
|
|
ContentType string // e.g. "audio/mpeg"; set alongside Audio
|
|
DirectURL string // speaker-fetchable URL; set instead of Audio
|
|
}
|
|
|
|
// Provider converts text to either a direct URL or audio bytes.
|
|
type Provider interface {
|
|
// Name returns the provider identifier (e.g. "translate", "google-cloud").
|
|
Name() string
|
|
// Synthesize converts req into a Result.
|
|
Synthesize(ctx context.Context, req Request) (Result, error)
|
|
}
|