Skip to content

Instantly share code, notes, and snippets.

@gusaiani
Created March 29, 2026 21:38
Show Gist options
  • Select an option

  • Save gusaiani/c511085e00730d273320f3db9d5213f8 to your computer and use it in GitHub Desktop.

Select an option

Save gusaiani/c511085e00730d273320f3db9d5213f8 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Narrate — stream text-to-speech with playback controls
# Usage:
# narrate <file> Read a file aloud
# narrate "some text" Read text aloud
# narrate pause Toggle play/pause
# narrate fwd Skip forward 30s
# narrate back Skip back 15s
# narrate stop Stop playback
# cat file | narrate Read piped text
SOCKET=/tmp/mpv-narrate
send_ipc() {
python3 -c "
import socket, sys
try:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('$SOCKET')
s.send(b'$1\n')
s.close()
except: pass
"
}
case "${1:-}" in
pause) send_ipc '{"command":["cycle","pause"]}'; exit ;;
fwd) send_ipc '{"command":["seek","30"]}'; exit ;;
back) send_ipc '{"command":["seek","-15"]}'; exit ;;
stop) send_ipc '{"command":["quit"]}'; exit ;;
esac
# Kill any existing narration
[ -S "$SOCKET" ] && send_ipc '{"command":["quit"]}' && sleep 0.3
# Determine input
TMPFILE=/tmp/narrate-text.txt
if [ -t 0 ] && [ -n "$1" ]; then
if [ -f "$1" ]; then
[ "$(realpath "$1")" != "$(realpath "$TMPFILE")" ] && cp "$1" "$TMPFILE"
else
echo "$*" > "$TMPFILE"
fi
else
cat > "$TMPFILE"
fi
# Detect language — if mostly Portuguese characters/words, use PT voice
VOICE="en-US-AndrewMultilingualNeural"
if grep -qiP 'ção|ões|não|também|então|através|é|ê|ã|õ' "$TMPFILE" 2>/dev/null; then
VOICE="pt-BR-AntonioNeural"
fi
echo "▶ Narrating ($(wc -w < "$TMPFILE" | tr -d ' ') words, voice: $VOICE)"
echo " Controls: narrate pause | fwd | back | stop"
edge-tts -f "$TMPFILE" --voice "$VOICE" --write-media /dev/stdout 2>/dev/null \
| mpv --no-video --no-terminal --input-ipc-server="$SOCKET" - 2>/dev/null &
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment