perf(discord): stream voice PCM to ffmpeg instead of a temp file

pcm_to_wav staged every captured utterance in a NamedTemporaryFile just to
hand ffmpeg an input path, then unlinked it. Feed the PCM to ffmpeg's stdin
instead: one fewer file created, written, read back and removed per voice
utterance, and the try/finally cleanup goes away with it.

The WAV output deliberately still goes to output_path rather than being
captured from stdout. ffmpeg cannot seek on a pipe, so a piped WAV is
written with placeholder 0xFFFFFFFF RIFF/data chunk sizes -- Python's wave
module then reports 2147483647 frames for a 1s clip, and strict readers
misjudge the length. Writing to the real path lets ffmpeg seek back and
patch the header.

Tests cover both halves: that the PCM goes over stdin with no temp file,
and (when ffmpeg is installed) that the resulting header reports the true
frame count.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Jesse Casco 2026-07-20 13:20:01 -04:00 committed by kshitij
parent 579672d87d
commit 70a3c2d9c9
2 changed files with 76 additions and 27 deletions

View File

@ -838,34 +838,32 @@ class VoiceReceiver:
@staticmethod
def pcm_to_wav(pcm_data: bytes, output_path: str,
src_rate: int = 48000, src_channels: int = 2):
"""Convert raw PCM to 16kHz mono WAV via ffmpeg."""
with tempfile.NamedTemporaryFile(suffix=".pcm", delete=False) as f:
f.write(pcm_data)
pcm_path = f.name
try:
from hermes_cli._subprocess_compat import windows_hide_flags
"""Convert raw PCM to 16kHz mono WAV via ffmpeg.
subprocess.run(
[
resolve_ffmpeg_executable(), "-y", "-loglevel", "error",
"-f", "s16le",
"-ar", str(src_rate),
"-ac", str(src_channels),
"-i", pcm_path,
"-ar", "16000",
"-ac", "1",
output_path,
],
check=True,
timeout=10,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
finally:
try:
os.unlink(pcm_path)
except OSError:
pass
The PCM is fed straight to ffmpeg's stdin, which avoids staging it in a
temp file on every utterance. The WAV is still written to *output_path*
rather than captured from stdout: ffmpeg cannot seek on a pipe, so a
piped WAV carries placeholder (0xFFFFFFFF) RIFF/data sizes that make
strict readers misreport the length.
"""
from hermes_cli._subprocess_compat import windows_hide_flags
subprocess.run(
[
resolve_ffmpeg_executable(), "-y", "-loglevel", "error",
"-f", "s16le",
"-ar", str(src_rate),
"-ac", str(src_channels),
"-i", "pipe:0",
"-ar", "16000",
"-ac", "1",
output_path,
],
input=pcm_data,
check=True,
timeout=10,
creationflags=windows_hide_flags(),
)
def _read_dm_role_auth_guild() -> Optional[int]:

View File

@ -1947,3 +1947,54 @@ class TestStreamTtsTempfileFallback:
)
# And the temp file is cleaned up afterwards.
assert not os.path.exists(played[0]), "temp WAV was not unlinked"
class TestPcmToWav:
"""pcm_to_wav streams PCM through ffmpeg's stdin, not a temp file."""
def test_pcm_is_piped_to_stdin_not_staged_on_disk(self, tmp_path):
from plugins.platforms.discord.adapter import VoiceReceiver
out = tmp_path / "out.wav"
with patch("plugins.platforms.discord.adapter.subprocess.run") as run:
VoiceReceiver.pcm_to_wav(b"\x00\x01" * 16, str(out))
args, kwargs = run.call_args
cmd = args[0]
assert kwargs["input"] == b"\x00\x01" * 16, "PCM must be fed via stdin"
assert "pipe:0" in cmd, "ffmpeg must read the PCM from stdin"
assert cmd[-1] == str(out), (
"the WAV must be written to the real path; ffmpeg cannot seek on a "
"pipe, so a piped WAV gets placeholder RIFF/data sizes"
)
assert not any(str(a).endswith(".pcm") for a in cmd), (
"no temp .pcm file should be staged"
)
@pytest.mark.skipif(
__import__("shutil").which("ffmpeg") is None, reason="ffmpeg not installed",
)
def test_output_wav_header_reports_true_length(self, tmp_path):
"""A piped-stdout WAV reports 0xFFFFFFFF sizes; the written file must not."""
import math
import struct
import wave
from plugins.platforms.discord.adapter import VoiceReceiver
frames = 48000 # 1s @ 48kHz stereo
pcm = b"".join(
struct.pack("<hh", v, v)
for v in (
int(20000 * math.sin(2 * math.pi * 440 * i / 48000))
for i in range(frames)
)
)
out = tmp_path / "out.wav"
VoiceReceiver.pcm_to_wav(pcm, str(out))
with wave.open(str(out)) as w:
assert w.getnchannels() == 1
assert w.getframerate() == 16000
# 48kHz -> 16kHz is a 3x decimation of a 1s clip.
assert w.getnframes() == 16000