Damus
nick profile picture
nick
@nick

peer-to-peer cash security

Relays (10)
  • wss://nostr-pub.wellorder.net/ – read & write
  • wss://nostr.bitcoiner.social/ – read & write
  • wss://nostr-pub.semisol.dev/ – read & write
  • wss://relay.damus.io/ – read & write
  • wss://relay.nostr.info/ – read & write
  • wss://relay.primal.net/ – read & write
  • wss://relay.snort.social/ – read & write
  • wss://purplepag.es/ – read & write
  • wss://relay.mostr.pub/ – read & write
  • wss://relay.0xchat.com/ – read & write

Recent Notes

calle · 4d
handy.computer
nick profile picture
i raise you

```
#!/bin/bash
# Toggle push-to-talk transcription. First run starts recording; second run
# stops, transcribes with whisper.cpp, and copies the text to the clipboard.
#
# Dependencies: arecord (alsa-utils), ffmpeg, whisper.cpp, dunstify (dunst),
# copyq. Adjust WHISPER_DIR / MODEL / clipboard command below to taste.

WHISPER_DIR="$HOME/ai/v2t/whisper.cpp"
MODEL="$WHISPER_DIR/models/ggml-base.en.bin"
AUDIO_FILE="/tmp/whisper_recording.wav"
PID_FILE="/tmp/whisper_record.pid"
LOCK_FILE="/tmp/whisper_record.lock"

notify() { dunstify -u "$1" "Whisper" "$2" -t "$3"; }

# Kill any leftover whisper-cli processes from previous runs
pkill -f "whisper-cli.*whisper_recording.wav" 2>/dev/null

# If a recording is in progress (PID file exists and the process is alive), stop it.
if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
# Prevent double-tap race: if already transcribing, bail out
if [ -f "$LOCK_FILE" ]; then
notify normal "Already processing..." 1500
exit 0
fi
touch "$LOCK_FILE"

PID=$(cat "$PID_FILE")
rm -f "$PID_FILE"

notify normal "Finishing recording..." 1500

# Keep recording briefly to capture trailing speech
sleep 1.5

# Stop arecord and wait for it to exit (force-kill if it hangs)
kill -INT "$PID" 2>/dev/null
for _ in $(seq 1 20); do
kill -0 "$PID" 2>/dev/null || break
sleep 0.1
done
kill -9 "$PID" 2>/dev/null
sleep 0.3

notify normal "Processing..." 5000

# Re-encode the wav: arecord may not finalize the header when killed
# from another shell, so rewrite it to a clean 16kHz mono file.
ffmpeg -y -i "$AUDIO_FILE" -ar 16000 -ac 1 -f wav "$AUDIO_FILE.fixed" 2>/dev/null
mv -f "$AUDIO_FILE.fixed" "$AUDIO_FILE"

if [ ! -s "$AUDIO_FILE" ]; then
notify critical "No audio recorded" 3000
rm -f "$AUDIO_FILE" "$LOCK_FILE"
exit 1
fi

cd "$WHISPER_DIR" || { rm -f "$LOCK_FILE"; exit 1; }
TEXT=$(./build/bin/whisper-cli -m "$MODEL" -f "$AUDIO_FILE" -nt -np 2>/dev/null | xargs)

if [ -n "$TEXT" ]; then
printf '%s' "$TEXT" | copyq copy -
notify normal "Copied to clipboard!" 2000
else
notify critical "No speech detected" 3000
fi

rm -f "$AUDIO_FILE" "$LOCK_FILE"
else
# Not recording: clean up any stale state and start a new recording.
rm -f "$PID_FILE" "$LOCK_FILE" "$AUDIO_FILE"

notify normal "Recording started... 🎤" 2000

arecord -f S16_LE -r 16000 -c 1 "$AUDIO_FILE" 2>/dev/null &
echo $! > "$PID_FILE"
fi
```


AND

```
#!/bin/bash
# Toggle live transcription with whisper.cpp's streaming mode. First run starts
# whisper-stream; second run stops it and copies the transcript to the clipboard.
#
# Dependencies: whisper.cpp (built with stream support), dunstify (dunst),
# copyq. Adjust WHISPER_DIR / MODEL / clipboard command below to taste.

WHISPER_DIR="$HOME/ai/v2t/whisper.cpp"
MODEL="$WHISPER_DIR/models/ggml-base.en.bin"
PID_FILE="/tmp/whisper_stream.pid"
TRANSCRIPT_FILE="/tmp/whisper_transcript.txt"

notify() { dunstify -u "$1" "Whisper" "$2" -t "$3"; }

# If a stream is running (PID file exists and the process is alive), stop it.
if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
PID=$(cat "$PID_FILE")

notify normal "Stopping recording..." 2000

# Let whisper finish processing the current audio chunk before stopping.
sleep 3

# SIGTERM first so the transcript is flushed, then force-kill if it hangs.
kill -TERM "$PID" 2>/dev/null
sleep 0.5
kill -9 "$PID" 2>/dev/null
sleep 0.2

# Pull just the text out of whisper-stream's "[timestamp] text" lines.
if [ -s "$TRANSCRIPT_FILE" ]; then
TEXT=$(grep -oP "\] +\K.*" "$TRANSCRIPT_FILE" | grep -v "^$" | tr '\n' ' ')
if [ -n "$TEXT" ]; then
printf '%s' "$TEXT" | copyq copy -
notify normal "Copied to clipboard!" 2000
else
notify critical "No speech detected" 3000
fi
else
notify critical "No transcript generated" 3000
fi

rm -f "$PID_FILE" "$TRANSCRIPT_FILE"
else
# Not recording: clean up any stale state and start a new stream.
rm -f "$PID_FILE" "$TRANSCRIPT_FILE"
cd "$WHISPER_DIR" || exit 1

notify normal "Recording started... 🎤" 2000

./build/bin/whisper-stream \
-m "$MODEL" \
-t 6 \
--step 0 \
--length 10000 \
-vth 0.75 \
--keep 0 \
-f "$TRANSCRIPT_FILE" \
>/dev/null 2>&1 &

echo $! > "$PID_FILE"
fi
```

❤️1
calle · 4d
handy.computer
nick · 4d
I primarily use for: - Bound Super+T to toggle audio recording --> clipboard - Transcribe past talks/workshops for refinement + fixups https://github.com/ggml-org/whisper.cpp
47 · 5d
yeah. drama
waxwing · 5d
It did occur to me but that's to solve a single user routing a larger amount. It probably "rhymes" though: fixed preimage on multiple routes.
Bitcoin Safe · 6d
Yes, githubs graph rendering isn't perfect.