fix(mic): harden capture session shutdown

- Prevent deadlock when stopping capture
- Make file recorder writes thread-safe
- Add idempotent close for recorder
- Cap waveIn devices and recover panics
- Validate mic device range in HTTP API
This commit is contained in:
2026-09-02 01:09:45 +03:00
parent eaa46e7494
commit 45f345123d
4 changed files with 200 additions and 104 deletions
+14 -6
View File
@@ -4,11 +4,13 @@ import (
"fmt"
"os"
"path/filepath"
"sync"
"tea.chunkbyte.com/kato/go-worm/lib/config"
)
type fileRecorder struct {
mu sync.Mutex
path string
f *os.File
written int64
@@ -37,9 +39,14 @@ func openRecorder(name string) (*fileRecorder, error) {
}
func (r *fileRecorder) Write(pcm []byte) error {
if len(pcm) == 0 {
if r == nil || len(pcm) == 0 {
return nil
}
r.mu.Lock()
defer r.mu.Unlock()
if r.f == nil {
return fmt.Errorf("recorder closed")
}
if r.written+int64(len(pcm)) > config.MaxUploadSize {
return fmt.Errorf("recording exceeds %d bytes", config.MaxUploadSize)
}
@@ -49,9 +56,14 @@ func (r *fileRecorder) Write(pcm []byte) error {
}
func (r *fileRecorder) Close() (int64, error) {
if r.f == nil {
if r == nil {
return 0, nil
}
r.mu.Lock()
defer r.mu.Unlock()
if r.f == nil {
return r.written, nil
}
hdr := make([]byte, wavHeaderSize)
writeWAVHeader(hdr, int(r.written))
if _, err := r.f.Seek(0, 0); err != nil {
@@ -68,7 +80,3 @@ func (r *fileRecorder) Close() (int64, error) {
r.f = nil
return r.written, err
}
func (r *fileRecorder) basename() string {
return filepath.Base(r.path)
}