Notifications for recording.

This commit is contained in:
Storm Dragon
2026-05-15 20:56:46 -04:00
parent 81a928e122
commit eef7454c0f
5 changed files with 107 additions and 8 deletions
+6 -1
View File
@@ -111,8 +111,13 @@ Each event has the following parameters:
- disconnect: you have disconnected from a server
- msg: the channel you are currently connected to has received a message
- pm: you have received a private message
- recordstart: you have started recording
- recordstop: you have stopped recording
- recorderror: recording could not start or stopped with an error
- userrecordstart: another user has started recording
- userrecordstop: another user has stopped recording
* who: the person causing initiation of the event ("me" for self-generated events)
* what: the body of the event as applicable (message, channel name, etc)
* what: the body of the event as applicable (message, channel name, recording path, error, etc)
Warning:
Keep in mind that Barnard opens an Alsa sound device when starting.
+2
View File
@@ -40,6 +40,8 @@ type Barnard struct {
UiInputStatus uiterm.Label
SelectedChannel *gumble.Channel
selectedUser *gumble.User
statusText string
statusNotice bool
notifyChannel chan []string
+52 -6
View File
@@ -22,6 +22,7 @@
#
#--code--
# shellcheck disable=SC2329
# 1 is off, 0 is on
notify=0
sound=0
@@ -68,17 +69,42 @@ msg() {
[[ $notify ]] && notify "$1 from $2: $3"
}
notify() {
if [[ "$notifyType" == "notify-send" ]]; then
notify-send "$@"
else
notify_fenrir() {
local message="$1"
local socatFile=""
if ! command -v socat > /dev/null 2>&1; then
return 1
fi
if [[ -e "/tmp/fenrirscreenreader-deamon.sock" ]]; then
socatFile="/tmp/fenrirscreenreader-deamon.sock"
else
socatFile="$(find /tmp/ -maxdepth 1 -type s -name 'fenrirscreenreader-*.sock' | head -1)"
fi
echo "command say $@" | socat - UNIX-CLIENT:$socatFile
fi
if [[ -z "$socatFile" ]]; then
return 1
fi
printf 'command say %s\n' "$message" | socat - "UNIX-CLIENT:$socatFile" > /dev/null 2>&1
}
notify_speech() {
local message="$1"
if command -v spd-say > /dev/null 2>&1; then
spd-say "$message" > /dev/null 2>&1 && return 0
fi
if command -v espeak-ng > /dev/null 2>&1; then
espeak-ng "$message" > /dev/null 2>&1 && return 0
fi
return 1
}
notify() {
local message="$*"
if [[ "$notifyType" == "notify-send" ]]; then
command -v notify-send > /dev/null 2>&1 && notify-send "$@" && return 0
else
notify_fenrir "$message" && return 0
fi
notify_speech "$message" || true
}
pm() {
@@ -86,6 +112,26 @@ pm() {
[[ $notify ]] && notify "$1 from $2: $3"
}
recordstart() {
[[ $notify ]] && notify "Recording started."
}
recordstop() {
[[ $notify ]] && notify "Recording stopped."
}
recorderror() {
[[ $notify ]] && notify "Recording error: $3"
}
userrecordstart() {
[[ $notify ]] && notify "$2 started recording."
}
userrecordstop() {
[[ $notify ]] && notify "$2 stopped recording."
}
status() {
# If transmitting: Payphone coin drop tones (1700+2200 Hz simultaneous, like quarter = 5 tones)
# If not transmitting: Special Information Tone (SIT) - call failed (913.8, 1370.6, 1776.7 Hz)
+27 -1
View File
@@ -42,12 +42,14 @@ func (b *Barnard) ToggleRecording() {
func (b *Barnard) StartRecording() {
if b.Client == nil || b.Client.Self == nil {
b.AddOutputLine("Recording requires an active server connection")
b.Notify("recorderror", "me", "Recording requires an active server connection")
return
}
b.RecordingMutex.Lock()
if b.recordingAllowed != nil && !*b.recordingAllowed {
b.RecordingMutex.Unlock()
b.AddOutputLine("Recording is not allowed by this server.")
b.Notify("recorderror", "me", "Recording is not allowed by this server.")
return
}
if b.Recorder != nil || b.recordingStarting {
@@ -60,6 +62,7 @@ func (b *Barnard) StartRecording() {
b.Client.Self.SetRecording(true)
b.AddOutputLine("Recording start requested")
b.renderGeneralStatus()
}
func (b *Barnard) StopRecording(notifyServer bool) {
@@ -70,20 +73,25 @@ func (b *Barnard) StopRecording(notifyServer bool) {
}
if wasPending {
b.AddOutputLine("Recording start cancelled")
b.Notify("recordstop", "me", "Recording start cancelled")
} else {
b.AddOutputLine("Recording is not active")
}
b.renderGeneralStatus()
return
}
if err := recorder.Stop(); err != nil {
b.AddOutputLine(fmt.Sprintf("Recording stopped with error: %s", err))
b.Notify("recorderror", "me", err.Error())
} else {
b.AddOutputLine(fmt.Sprintf("Recording saved: %s", path))
b.Notify("recordstop", "me", path)
}
if notifyServer && b.Client != nil && b.Client.Self != nil {
b.Client.Self.SetRecording(false)
}
b.renderGeneralStatus()
}
func (b *Barnard) StopRecordingIfActive(notifyServer bool) {
@@ -114,8 +122,10 @@ func (b *Barnard) HandleRecordingChange(e *gumble.UserChangeEvent) {
}
if e.User.Recording {
b.AddOutputLine(fmt.Sprintf("%s started recording", e.User.Name))
b.Notify("userrecordstart", e.User.Name, "")
} else {
b.AddOutputLine(fmt.Sprintf("%s stopped recording", e.User.Name))
b.Notify("userrecordstop", e.User.Name, "")
}
}
@@ -130,6 +140,7 @@ func (b *Barnard) HandleRecordingAllowed(allowed *bool) {
b.RecordingMutex.Unlock()
if !value && active {
b.AddOutputLine("Recording is not allowed by this server.")
b.Notify("recorderror", "me", "Recording is not allowed by this server.")
b.StopRecording(true)
}
}
@@ -154,7 +165,9 @@ func (b *Barnard) finishRecordingStart() {
b.recordingStarting = false
b.RecordingMutex.Unlock()
b.AddOutputLine(fmt.Sprintf("Could not start recording: %s", err))
b.Notify("recorderror", "me", err.Error())
b.Client.Self.SetRecording(false)
b.renderGeneralStatus()
return
}
@@ -171,6 +184,14 @@ func (b *Barnard) finishRecordingStart() {
b.Stream.SetRecorder(recorder)
}
b.AddOutputLine(fmt.Sprintf("Recording started: %s", recorder.Path()))
b.Notify("recordstart", "me", recorder.Path())
b.renderGeneralStatus()
}
func (b *Barnard) isRecordingActive() bool {
b.RecordingMutex.Lock()
defer b.RecordingMutex.Unlock()
return b.Recorder != nil || b.recordingStarting
}
func (b *Barnard) detachRecorder() (*recording.Recorder, string, bool) {
@@ -191,10 +212,15 @@ func (b *Barnard) detachRecorder() (*recording.Recorder, string, bool) {
}
func (b *Barnard) stopRecordingForDisconnect() {
recorder, _, _ := b.detachRecorder()
recorder, path, _ := b.detachRecorder()
if recorder != nil {
if err := recorder.Stop(); err != nil {
b.AddOutputLine(fmt.Sprintf("Recording stopped with error: %s", err))
b.Notify("recorderror", "me", err.Error())
} else {
b.AddOutputLine(fmt.Sprintf("Recording saved: %s", path))
b.Notify("recordstop", "me", path)
}
}
b.renderGeneralStatus()
}
+20
View File
@@ -115,6 +115,14 @@ func (b *Barnard) OnVoiceEffectCycle(ui *uiterm.Ui, key uiterm.Key) {
}
func (b *Barnard) UpdateGeneralStatus(text string, notice bool) {
b.statusText = text
b.statusNotice = notice
b.renderGeneralStatus()
}
func (b *Barnard) renderGeneralStatus() {
text := b.statusText
notice := b.statusNotice
if notice {
b.UiStatus.Fg = uiterm.ColorWhite | uiterm.AttrBold
b.UiStatus.Bg = uiterm.ColorRed
@@ -122,6 +130,16 @@ func (b *Barnard) UpdateGeneralStatus(text string, notice bool) {
b.UiStatus.Fg = uiterm.ColorBlack
b.UiStatus.Bg = uiterm.ColorWhite
}
if b.isRecordingActive() {
switch strings.TrimSpace(text) {
case "Idle":
text = " Idle Rec "
case "Tx":
text = " Tx Rec "
case "File":
text = " File Rec "
}
}
b.UiStatus.Text = text
b.Ui.Refresh()
}
@@ -423,6 +441,8 @@ func (b *Barnard) OnUiInitialize(ui *uiterm.Ui) {
Fg: uiterm.ColorBlack,
Bg: uiterm.ColorWhite,
}
b.statusText = b.UiStatus.Text
b.statusNotice = false
ui.Add(uiViewStatus, &b.UiStatus)
b.UiInput = uiterm.Textbox{