mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 19:06:11 +00:00
Handle pw-record versions without raw support
This commit is contained in:
@@ -197,7 +197,7 @@ def recording_command(target=""):
|
||||
return cmd
|
||||
if shutil.which("pw-record"):
|
||||
cmd = [
|
||||
"pw-record", "--raw", f"--rate={RATE}",
|
||||
"pw-record", *_pw_record_raw_option(), f"--rate={RATE}",
|
||||
f"--channels={CHANNELS}", "--format=s16",
|
||||
]
|
||||
if target:
|
||||
@@ -207,6 +207,25 @@ def recording_command(target=""):
|
||||
return []
|
||||
|
||||
|
||||
def _pw_record_raw_option():
|
||||
"""Use --raw only on pw-record releases that provide it.
|
||||
|
||||
PipeWire 1.0, including Ubuntu 24.04's build, writes raw PCM to stdout but
|
||||
rejects the newer --raw option. A rejected option ends the recorder before
|
||||
it receives sound, so ask the installed binary which form it understands.
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["pw-record", "--help"], capture_output=True, text=True, timeout=2
|
||||
)
|
||||
help_text = (result.stdout or "") + (result.stderr or "")
|
||||
except (subprocess.SubprocessError, OSError):
|
||||
return ["--raw"] # preserve the existing command when probing itself fails
|
||||
if not help_text.strip():
|
||||
return ["--raw"]
|
||||
return ["--raw"] if "--raw" in help_text else []
|
||||
|
||||
|
||||
class MeetingRecorder(QObject):
|
||||
"""Microphone and speaker output into one stereo file: left is you, right is
|
||||
everyone else.
|
||||
|
||||
@@ -230,6 +230,23 @@ class RecordingCommand(DikteTest):
|
||||
with only_these_tools("pw-record"):
|
||||
self.assertEqual(audio.recording_command()[0], "pw-record")
|
||||
|
||||
def test_pw_record_uses_raw_when_the_installed_version_supports_it(self):
|
||||
help_result = FakeCompleted(stdout=" --raw Write raw samples\n")
|
||||
with only_these_tools("pw-record"), \
|
||||
mock.patch.object(audio.subprocess, "run", return_value=help_result):
|
||||
self.assertIn("--raw", audio.recording_command())
|
||||
|
||||
def test_pw_record_omits_raw_when_pipewire_1_0_rejects_it(self):
|
||||
help_result = FakeCompleted(stdout=" --rate Sample rate\n")
|
||||
with only_these_tools("pw-record"), \
|
||||
mock.patch.object(audio.subprocess, "run", return_value=help_result):
|
||||
self.assertNotIn("--raw", audio.recording_command())
|
||||
|
||||
def test_pw_record_help_failure_keeps_the_existing_command(self):
|
||||
with only_these_tools("pw-record"), \
|
||||
mock.patch.object(audio.subprocess, "run", side_effect=OSError):
|
||||
self.assertIn("--raw", audio.recording_command())
|
||||
|
||||
def test_neither_is_installed(self):
|
||||
with only_these_tools():
|
||||
self.assertEqual(audio.recording_command(), [])
|
||||
@@ -282,6 +299,7 @@ class RecorderChain(DikteTest):
|
||||
recorder.failed.connect(failures.append)
|
||||
proc = FakeProcess(data)
|
||||
with only_these_tools("pw-record"), \
|
||||
mock.patch.object(audio, "_pw_record_raw_option", return_value=[]), \
|
||||
mock.patch.object(subprocess, "Popen", return_value=proc) as popen:
|
||||
recorder.start(target=target, max_seconds=max_seconds)
|
||||
recorder._thread.join(timeout=5)
|
||||
@@ -328,6 +346,7 @@ class RecorderChain(DikteTest):
|
||||
recorder.stopped.connect(lambda *args: results.append(args))
|
||||
proc = FakeProcess(tone(1.0))
|
||||
with only_these_tools("pw-record"), \
|
||||
mock.patch.object(audio, "_pw_record_raw_option", return_value=[]), \
|
||||
mock.patch.object(subprocess, "Popen", return_value=proc):
|
||||
recorder.start()
|
||||
recorder._thread.join(timeout=5)
|
||||
|
||||
Reference in New Issue
Block a user