diff --git a/README.md b/README.md index 7260e66..12a5d61 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ The daemon automatically creates `~/.config/hyprvoice/config.toml` with helpful buffer_size = 8192 # Internal buffer size in bytes (larger = less CPU, more latency) device = "" # PipeWire audio device (empty = use default microphone) channel_buffer_size = 30 # Audio frame buffer size (frames to buffer) + timeout = "5m" # Maximum recording duration (e.g., "30s", "2m", "5m") # Speech Transcription Configuration [transcription] @@ -257,8 +258,15 @@ format = "s16" # Audio format (s16 recommended) buffer_size = 8192 # Internal buffer size in bytes device = "" # PipeWire device (empty for default) channel_buffer_size = 30 # Audio frame buffer size +timeout = "5m" # Maximum recording duration (prevents runaway recordings) ``` +**Recording Timeout:** +- Prevents accidental long recordings that could consume resources +- Default: 5 minutes (`"5m"`) +- Format: Go duration strings like `"30s"`, `"2m"`, `"10m"` +- Recording automatically stops when timeout is reached + #### Text Injection Configurable text injection with multiple modes: diff --git a/internal/config/config.go b/internal/config/config.go index 8e36a6d..9421c7b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,12 +21,13 @@ type Config struct { } type RecordingConfig struct { - SampleRate int `toml:"sample_rate"` - Channels int `toml:"channels"` - Format string `toml:"format"` - BufferSize int `toml:"buffer_size"` - Device string `toml:"device"` - ChannelBufferSize int `toml:"channel_buffer_size"` + SampleRate int `toml:"sample_rate"` + Channels int `toml:"channels"` + Format string `toml:"format"` + BufferSize int `toml:"buffer_size"` + Device string `toml:"device"` + ChannelBufferSize int `toml:"channel_buffer_size"` + Timeout time.Duration `toml:"timeout"` } type TranscriptionConfig struct { @@ -56,6 +57,7 @@ func (c *Config) ToRecordingConfig() recording.Config { BufferSize: c.Recording.BufferSize, Device: c.Recording.Device, ChannelBufferSize: c.Recording.ChannelBufferSize, + Timeout: c.Recording.Timeout, } } @@ -100,6 +102,9 @@ func (c *Config) Validate() error { if c.Recording.Format == "" { return fmt.Errorf("invalid recording.format: empty") } + if c.Recording.Timeout <= 0 { + return fmt.Errorf("invalid recording.timeout: %v", c.Recording.Timeout) + } // Transcription if c.Transcription.Provider == "" { @@ -228,6 +233,7 @@ func SaveDefaultConfig() error { buffer_size = 8192 # Internal buffer size in bytes (larger = less CPU, more latency) device = "" # PipeWire audio device (empty = use default microphone) channel_buffer_size = 30 # Audio frame buffer size (frames to buffer) + timeout = "5m" # Maximum recording duration (e.g., "30s", "2m", "5m") # Speech Transcription Configuration [transcription] diff --git a/internal/pipeline/pipeline.go b/internal/pipeline/pipeline.go index 1a74ce2..16aeee7 100644 --- a/internal/pipeline/pipeline.go +++ b/internal/pipeline/pipeline.go @@ -5,7 +5,6 @@ import ( "log" "sync" "sync/atomic" - "time" "github.com/leonardotrapani/hyprvoice/internal/config" "github.com/leonardotrapani/hyprvoice/internal/injection" @@ -68,7 +67,7 @@ func (p *pipeline) Run(ctx context.Context) { return } - runCtx, cancel := context.WithTimeout(ctx, 5*time.Minute) + runCtx, cancel := context.WithTimeout(ctx, p.config.Recording.Timeout) p.setCancel(cancel) p.wg.Add(1) diff --git a/internal/recording/recording.go b/internal/recording/recording.go index cf30cea..a378e62 100644 --- a/internal/recording/recording.go +++ b/internal/recording/recording.go @@ -26,6 +26,7 @@ type Config struct { BufferSize int Device string ChannelBufferSize int + Timeout time.Duration } type Recorder struct {