Add canonical audio preparation and meeting context support
This commit is contained in:
+75
-1
@@ -1,11 +1,14 @@
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from dataclasses import replace
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from scripts import run_mvp_meeting as cli
|
||||
from src.meeting_lab.audio import PreparedAudio
|
||||
from src.meeting_lab.models.meeting_context import load_meeting_context
|
||||
from src.meeting_lab.orchestration import mvp as mvp_api
|
||||
from src.meeting_lab.orchestration.mvp import MvpMeetingConfig, MvpRunResult
|
||||
@@ -71,6 +74,12 @@ def fake_transcribe(audio, model, output, language, **kwargs):
|
||||
return TranscriptionResult(output, raw, transcript, text, metadata, 0.1)
|
||||
|
||||
|
||||
def fake_prepare(source, destination, **kwargs):
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copyfile(source, destination)
|
||||
return PreparedAudio(source, source.suffix.removeprefix("."), destination, "ffmpeg", "ffmpeg")
|
||||
|
||||
|
||||
def fake_protocol(transcript, context, **kwargs):
|
||||
rendered_context = load_meeting_context(context)
|
||||
assert rendered_context.meeting_id == "programmatic-test"
|
||||
@@ -103,6 +112,7 @@ class MvpApiTests(unittest.TestCase):
|
||||
events = []
|
||||
with (
|
||||
patch.object(mvp_api, "transcribe_audio", side_effect=fake_transcribe),
|
||||
patch.object(mvp_api, "prepare_audio", side_effect=fake_prepare),
|
||||
patch.object(
|
||||
mvp_api, "generate_direct_protocol", side_effect=fake_protocol
|
||||
),
|
||||
@@ -142,7 +152,7 @@ class MvpApiTests(unittest.TestCase):
|
||||
mvp_api,
|
||||
"transcribe_audio",
|
||||
side_effect=TranscriptionError("stopped"),
|
||||
):
|
||||
), patch.object(mvp_api, "prepare_audio", side_effect=fake_prepare):
|
||||
result = mvp_api.run_mvp_meeting(config, progress_sink=events.append)
|
||||
|
||||
self.assertEqual(result.exit_code, 2)
|
||||
@@ -168,8 +178,72 @@ class MvpApiTests(unittest.TestCase):
|
||||
self.assertEqual(delegated.diarization, "off")
|
||||
self.assertEqual(delegated.language, "de")
|
||||
self.assertEqual(delegated.whisper_executable, "whisper-cli")
|
||||
self.assertEqual(delegated.ffmpeg_executable, "ffmpeg")
|
||||
self.assertTrue(delegated.audio_normalization)
|
||||
self.assertEqual(api.call_args.kwargs["meeting_context"], context_data())
|
||||
|
||||
def test_cli_explicit_audio_normalization_values_are_propagated(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
config = self.config(root)
|
||||
enabled = cli.config_from_args(
|
||||
cli.parse_args(
|
||||
[
|
||||
str(config.audio_file),
|
||||
"--whisper-model",
|
||||
str(config.whisper_model),
|
||||
"--audio-normalization",
|
||||
]
|
||||
)
|
||||
)
|
||||
disabled = cli.config_from_args(
|
||||
cli.parse_args(
|
||||
[
|
||||
str(config.audio_file),
|
||||
"--whisper-model",
|
||||
str(config.whisper_model),
|
||||
"--no-audio-normalization",
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
self.assertTrue(enabled.audio_normalization)
|
||||
self.assertFalse(disabled.audio_normalization)
|
||||
|
||||
def test_transcription_receives_prepared_wav_for_encoded_inputs(self):
|
||||
for suffix in (".flac", ".m4a"):
|
||||
with self.subTest(suffix=suffix), tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
config = self.config(root)
|
||||
encoded = config.audio_file.with_suffix(suffix)
|
||||
config.audio_file.rename(encoded)
|
||||
config = replace(config, audio_file=encoded)
|
||||
received = []
|
||||
|
||||
def capture_transcribe(audio, *args, received_paths=received, **kwargs):
|
||||
received_paths.append(audio)
|
||||
return fake_transcribe(audio, *args, **kwargs)
|
||||
|
||||
with (
|
||||
patch.object(mvp_api, "prepare_audio", side_effect=fake_prepare),
|
||||
patch.object(mvp_api, "transcribe_audio", side_effect=capture_transcribe),
|
||||
patch.object(mvp_api, "generate_direct_protocol", side_effect=fake_protocol),
|
||||
):
|
||||
result = mvp_api.run_mvp_meeting(
|
||||
config, meeting_context=context_data()
|
||||
)
|
||||
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
self.assertEqual(received, [result.run_dir / "audio" / "prepared.wav"])
|
||||
manifest = json.loads(
|
||||
(result.run_dir / "audio" / "input_manifest.json").read_text()
|
||||
)
|
||||
self.assertEqual(manifest["format"], suffix.removeprefix("."))
|
||||
self.assertEqual(
|
||||
manifest["prepared_audio"]["prepared_audio_path"],
|
||||
str((result.run_dir / "audio" / "prepared.wav").resolve()),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user