When the QQ Music (or other) API server is not running, the bot now
returns a user-friendly message instead of crashing with a raw
ECONNREFUSED error. Applied to cmdPlay, cmdAdd, and the generic
command error handler.
https://claude.ai/code/session_01Niz9kmZ4zqfe3PWc6tjvMw
The pino logger's ThreadStream was throwing unhandled EINTR errors
when FFmpeg child processes were spawned, crashing the entire bot.
Add an error handler to suppress EINTR and prevent process crashes.
https://claude.ai/code/session_01EjpEsC2GCsvwbu4n3XC8EE
The ffmpeg-static bundled binary was crashing immediately (exitCode: null,
no data produced). Now we run `ffmpeg -version` to verify the binary works
before selecting it, with automatic fallback to system ffmpeg.
Also logs ffmpeg binary path at info level and captures signal in close event.
https://claude.ai/code/session_01EjpEsC2GCsvwbu4n3XC8EE
Adds info-level logs at each stage of the audio pipeline to help
diagnose why playback produces no audible output:
- FFmpeg first PCM data received
- FFmpeg process exit code
- FFmpeg stderr (errors/HTTP/stream info at info level)
- First opus frame encoded and emitted
- First voice packet sent to TeamSpeak
- Error catching in frame encoding loop
https://claude.ai/code/session_01EjpEsC2GCsvwbu4n3XC8EE
Avoid repeated filesystem checks on every play() call by resolving
the ffmpeg binary path once at module load. Also verify execute
permission after chmod to handle noexec mounts.
https://claude.ai/code/session_01CqfKgV8GuCmWNpfx86H62X
The bundled ffmpeg-static binary may lose execute permission after npm
install on some platforms, causing EACCES errors during playback. Now
checks and fixes the permission automatically before spawning ffmpeg.
https://claude.ai/code/session_01CqfKgV8GuCmWNpfx86H62X