tangled
alpha
login
or
join now
davidgasquez.com
/
dotfiles
1
fork
atom
🔧 Where my dotfiles lives in harmony and peace, most of the time
1
fork
atom
overview
issues
pulls
pipelines
✨ Replace waystt with whispr transcription hotkey
davidgasquez.com
2 months ago
177ac73f
0e3190c1
+118
-2
4 changed files
expand all
collapse all
unified
split
hypr
hyprland.conf
setup.sh
scripts
whispr
system
setup.sh
+1
-1
hypr/hyprland.conf
···
212
bind = $mainMod SHIFT, E, exec, uwsm app -- bemoji -n
213
214
# Whisper
215
-
bind = $mainMod SHIFT, O, exec, pgrep -x waystt >/dev/null && pkill --signal SIGUSR1 waystt || (waystt --pipe-to wl-copy &)
216
217
# Volume
218
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 2%+
···
212
bind = $mainMod SHIFT, E, exec, uwsm app -- bemoji -n
213
214
# Whisper
215
+
bind = $mainMod SHIFT, O, exec, whispr
216
217
# Volume
218
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 2%+
-1
hypr/setup.sh
···
27
pipewire-libcamera
28
playerctl
29
waybar
30
-
waystt-bin
31
wireplumber
32
wl-clip-persist
33
wl-clipboard
···
27
pipewire-libcamera
28
playerctl
29
waybar
0
30
wireplumber
31
wl-clip-persist
32
wl-clipboard
+116
scripts/whispr
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
#!/usr/bin/env bash
2
+
set -euo pipefail
3
+
4
+
# Whispr - Groq Whisper Transcription Script
5
+
# Based on https://github.com/EmbeddedMhawar/groq-whisper-linux/blob/master/groq_whisper.sh
6
+
7
+
API_KEY="${GROQ_API_KEY:-}"
8
+
if [[ -z "$API_KEY" ]]; then
9
+
notify-send -u critical "Groq Error" "Missing GROQ_API_KEY"
10
+
exit 1
11
+
fi
12
+
13
+
STATE_DIR="${XDG_RUNTIME_DIR:-/tmp}/whisp"
14
+
mkdir -p "$STATE_DIR"
15
+
16
+
FILENAME="${STATE_DIR}/rec.flac"
17
+
PIDFILE="${STATE_DIR}/rec.pid"
18
+
REC_LOG="${STATE_DIR}/rec_error.log"
19
+
CURL_LOG="${STATE_DIR}/curl_error.log"
20
+
ERROR_LOG="${STATE_DIR}/error.log"
21
+
22
+
if [ -f "$PIDFILE" ]; then
23
+
PID="$(<"$PIDFILE")"
24
+
if kill -0 "$PID" 2>/dev/null; then
25
+
notify-send -u low -t 1000 "Groq" "Finishing..."
26
+
sleep 1
27
+
kill -INT "$PID" 2>/dev/null || true
28
+
for _ in {1..50}; do
29
+
kill -0 "$PID" 2>/dev/null || break
30
+
sleep 0.1
31
+
done
32
+
fi
33
+
rm "$PIDFILE"
34
+
35
+
notify-send -u low -t 2000 "Groq" "Transcribing..."
36
+
37
+
if [[ ! -s "$FILENAME" ]]; then
38
+
{
39
+
echo "Error: recording file missing or empty: $FILENAME"
40
+
[[ -s "$REC_LOG" ]] && { echo; echo "--- rec stderr ---"; cat "$REC_LOG"; }
41
+
} >"$ERROR_LOG"
42
+
notify-send -u critical "Groq Error" "No audio captured. Check $ERROR_LOG"
43
+
exit 1
44
+
fi
45
+
46
+
MAX_RETRIES=3
47
+
RETRY_DELAY=1
48
+
HTTP_CODE=""
49
+
TEXT=""
50
+
51
+
: >"$CURL_LOG"
52
+
53
+
attempt=0
54
+
while (( attempt < MAX_RETRIES )); do
55
+
attempt=$((attempt + 1))
56
+
CURL_BODY="$(mktemp -p "$STATE_DIR" whisp_curl_body.XXXXXX)"
57
+
set +e
58
+
HTTP_CODE="$(curl -sS -o "$CURL_BODY" -w "%{http_code}" "https://api.groq.com/openai/v1/audio/transcriptions" \
59
+
-H "Authorization: Bearer $API_KEY" \
60
+
-F "file=@$FILENAME" \
61
+
-F "model=whisper-large-v3" \
62
+
-F "response_format=text" \
63
+
--connect-timeout 15 \
64
+
--max-time 300 \
65
+
2>>"$CURL_LOG")"
66
+
CURL_EXIT=$?
67
+
set -e
68
+
TEXT="$(<"$CURL_BODY")"
69
+
rm -f "$CURL_BODY"
70
+
71
+
if [[ $CURL_EXIT -ne 0 ]]; then
72
+
HTTP_CODE="000"
73
+
fi
74
+
75
+
if [[ "$HTTP_CODE" == "200" ]]; then
76
+
break
77
+
fi
78
+
79
+
# Retry on transient errors
80
+
if [[ "$HTTP_CODE" =~ ^(400|429|500|502|503|504)$ ]] && [[ $attempt -lt $MAX_RETRIES ]]; then
81
+
notify-send -u low -t 1500 "Groq" "Retrying... (attempt $((attempt+1))/$MAX_RETRIES)"
82
+
sleep $RETRY_DELAY
83
+
RETRY_DELAY=$((RETRY_DELAY * 2))
84
+
else
85
+
break
86
+
fi
87
+
done
88
+
89
+
if [[ "$HTTP_CODE" != "200" ]]; then
90
+
{
91
+
echo "Error (HTTP $HTTP_CODE) after $attempt attempts:"
92
+
[[ -n "${TEXT:-}" ]] && echo "$TEXT"
93
+
[[ -s "$CURL_LOG" ]] && { echo; echo "--- curl stderr (tail) ---"; tail -n 50 "$CURL_LOG"; }
94
+
} >"$ERROR_LOG"
95
+
notify-send -u critical "Groq Error" "Failed (Code $HTTP_CODE). Check $ERROR_LOG"
96
+
exit 1
97
+
else
98
+
printf %s "$TEXT" | wl-copy
99
+
notify-send -u low -t 2000 "Groq" "Transcription Done!"
100
+
fi
101
+
102
+
else
103
+
: >"$REC_LOG"
104
+
rec -q -r 16000 -c 1 -b 16 "$FILENAME" 2>"$REC_LOG" &
105
+
PID=$!
106
+
echo "$PID" > "$PIDFILE"
107
+
108
+
sleep 0.1
109
+
if ! kill -0 "$PID" 2>/dev/null; then
110
+
rm -f "$PIDFILE"
111
+
notify-send -u critical "Groq Error" "Recording failed. Check $REC_LOG"
112
+
exit 1
113
+
fi
114
+
115
+
notify-send -u low -t 1000 "Groq" "Listening... (press again to finish)"
116
+
fi
+1
system/setup.sh
···
20
power-profiles-daemon
21
preload
22
rocm-smi-lib
0
23
ufw
24
util-linux
25
xdg-user-dirs
···
20
power-profiles-daemon
21
preload
22
rocm-smi-lib
23
+
sox
24
ufw
25
util-linux
26
xdg-user-dirs