Search code examples
bashcurlcommand-line-interfacestring-interpolation

Text-to-speech from the command line via cloud API


I am trying to define a one-liner alias like the following:

alias speak='curl -G --data-urlencode "text=$(cat /dev/stdin)" "https://speech.botiumbox.com/api/tts/en?&tts=marytts" -H "accept: audio/wav" | mpv -'

such that I can use it like this

echo Hello World! | speak
speak Hello World!
speak<RET> # continuously do TTS per line until ^D
Hello World!
Another line!
<Ctrl-D>

The API I am using works if I use

curl -G --data-urlencode "text=Hello World!" "https://speech.botiumbox.com/api/tts/en?&tts=marytts" -H "accept: audio/wav" | mpv -

As demonstrated above, simply taking the standard input by cat /dev/stdin didn't seem to create a interactive CLI program. Any ideas to wrap this API into an interactive CLI program? Ideally, be POSIX compliant so it can run in a bash shell in Unixen.


Solution

  • I found a workaround that uses bash functions instead of an alias. The function marySpeak takes a string, sends it online for TTS then plays it back with mpv. Everything is defined as a oneliner, so can be placed in your .bashrc:

    marySpeak() { curl -s -G --data-urlencode "text=$1" "https://speech.botiumbox.com/api/tts/en?&tts=marytts" -H "accept: audio/wav" | mpv - 2>&1 > /dev/null; } 
    
    # then simply use it like this
    marySpeak "hello world!"
    

    Tested in GNU/Linux and macOS.