mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-24 14:47:23 +00:00
refactor(cli): move Cloud TTS under speaker tts-cloud, use global --host
Replaces the awkward top-level `tts speak --speaker-host` with a `speaker tts-cloud` subcommand that sits alongside the existing `speaker tts` and uses the global --host flag (--device still works as an alternative). The two are now clearly related: `speaker tts` sends a Google Translate URL straight to the speaker, while `speaker tts-cloud` routes through the service for server-side synthesis (Cloud TTS) and playback. --speaker-host is gone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e6d5588b99
commit
22c3142a79
@@ -11,30 +11,21 @@ import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// ttsCommand assembles the `soundtouch-cli tts …` command group. Unlike
|
||||
// `speaker tts` (which talks to a speaker directly using the Google Translate
|
||||
// URL), these subcommands call the AfterTouch service, which synthesizes audio
|
||||
// with the configured provider (e.g. Google Cloud TTS) and plays it on a
|
||||
// speaker. They require --service-url.
|
||||
func ttsCommand() *cli.Command {
|
||||
// ttsCloudCmd is the `speaker tts-cloud` subcommand. Unlike `speaker tts`
|
||||
// (which sends a Google Translate URL straight to the speaker), this routes
|
||||
// through the AfterTouch service, which synthesizes the audio with the
|
||||
// configured provider (e.g. Google Cloud TTS), hosts it, and plays it on the
|
||||
// speaker. It therefore needs --service-url. Target the speaker with the global
|
||||
// --host, or with --device (resolved to an IP by the service).
|
||||
func ttsCloudCmd() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "tts",
|
||||
Usage: "Text-to-speech via the AfterTouch service (Google Cloud TTS or Google Translate)",
|
||||
Description: "Sends text to the AfterTouch service, which synthesizes audio (or builds a\n" +
|
||||
"direct URL) and plays it on a speaker via the /speaker endpoint.\n\n" +
|
||||
"This differs from 'speaker tts', which talks to a speaker directly using\n" +
|
||||
"the Google Translate URL. Use 'tts speak' for the service's configured\n" +
|
||||
"provider (e.g. Google Cloud TTS).",
|
||||
Subcommands: []*cli.Command{
|
||||
ttsSpeakCmd(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ttsSpeakCmd() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "speak",
|
||||
Usage: "Synthesize text and play it on a speaker via the AfterTouch service",
|
||||
Name: "tts-cloud",
|
||||
Usage: "Speak text via the AfterTouch service (Google Cloud TTS), synthesized server-side",
|
||||
Description: "Routes through the AfterTouch service (requires --service-url), which\n" +
|
||||
"synthesizes the audio with the configured provider, hosts it, and plays it\n" +
|
||||
"on the speaker. Target the speaker with the global --host or with --device.\n\n" +
|
||||
"Contrast with 'speaker tts', which sends a Google Translate URL directly to\n" +
|
||||
"the speaker without involving the service.",
|
||||
Flags: append(CloudCommonFlags,
|
||||
&cli.StringFlag{
|
||||
Name: "text",
|
||||
@@ -45,11 +36,7 @@ func ttsSpeakCmd() *cli.Command {
|
||||
&cli.StringFlag{
|
||||
Name: "device",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Target device ID (the service resolves it to an IP)",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "speaker-host",
|
||||
Usage: "Target speaker IP/hostname (alternative to --device)",
|
||||
Usage: "Target device ID (the service resolves it to an IP); alternative to --host",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "language",
|
||||
@@ -71,17 +58,17 @@ func ttsSpeakCmd() *cli.Command {
|
||||
Value: "radio",
|
||||
},
|
||||
),
|
||||
Action: ttsSpeak,
|
||||
Action: ttsCloud,
|
||||
}
|
||||
}
|
||||
|
||||
func ttsSpeak(c *cli.Context) error {
|
||||
func ttsCloud(c *cli.Context) error {
|
||||
serviceURL := strings.TrimRight(c.String("service-url"), "/")
|
||||
device := c.String("device")
|
||||
speakerHost := c.String("speaker-host")
|
||||
host := c.String("host") // global flag
|
||||
|
||||
if device == "" && speakerHost == "" {
|
||||
return fmt.Errorf("one of --device or --speaker-host is required")
|
||||
if device == "" && host == "" {
|
||||
return fmt.Errorf("one of --host or --device is required")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{"text": c.String("text")}
|
||||
@@ -89,8 +76,8 @@ func ttsSpeak(c *cli.Context) error {
|
||||
payload["deviceId"] = device
|
||||
}
|
||||
|
||||
if speakerHost != "" {
|
||||
payload["host"] = speakerHost
|
||||
if host != "" {
|
||||
payload["host"] = host
|
||||
}
|
||||
|
||||
if l := c.String("language"); l != "" {
|
||||
|
||||
@@ -1941,6 +1941,7 @@ func main() {
|
||||
Action: playNotificationBeep,
|
||||
Before: RequireHost,
|
||||
},
|
||||
ttsCloudCmd(),
|
||||
{
|
||||
Name: "help",
|
||||
Usage: "Show detailed help about speaker functionality",
|
||||
@@ -2315,7 +2316,6 @@ func main() {
|
||||
// AfterTouch service management (sources, accounts, devices).
|
||||
// Defined in cmd_cloud.go.
|
||||
app.Commands = append(app.Commands, cloudCommand())
|
||||
app.Commands = append(app.Commands, ttsCommand())
|
||||
|
||||
// Sort commands alphabetically (including subcommands and flags recursively)
|
||||
sortCommands(app.Commands)
|
||||
|
||||
@@ -317,16 +317,19 @@ curl -X POST http://soundtouch.local:8000/setup/tts/speak \
|
||||
-d '{"host":"192.0.2.100","text":"Dinner is ready"}'
|
||||
```
|
||||
|
||||
`deviceId` may be used instead of `host` (the service resolves it to an IP from
|
||||
its datastore). Optional fields: `language`, `voice`, `volume`.
|
||||
`deviceId` may be used instead of `host` (the service resolves it to an IP from its datastore). Optional fields: `language`, `voice`, `volume`, and `method`
|
||||
(`radio`, the default LOCAL_INTERNET_RADIO path, or `speaker`, the /speaker
|
||||
notification path that ducks and resumes playback).
|
||||
|
||||
CLI (calls the service, not the speaker directly):
|
||||
CLI (`speaker tts-cloud` routes through the service for Cloud TTS, in contrast
|
||||
to `speaker tts` which sends a Google Translate URL straight to the speaker):
|
||||
|
||||
```bash
|
||||
soundtouch-cli tts speak \
|
||||
soundtouch-cli speaker tts-cloud \
|
||||
--service-url http://soundtouch.local:8000 \
|
||||
--speaker-host 192.0.2.100 \
|
||||
--text "Dinner is ready"
|
||||
--host 192.0.2.100 \
|
||||
--text "Dinner is ready" \
|
||||
--method speaker
|
||||
```
|
||||
|
||||
Web UI: the TTS source view (and the Play URL view) include a "Say something…"
|
||||
|
||||
Reference in New Issue
Block a user