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