"""Verifies clap detection analyzes whichever audio track mpv is actually playing, not whichever one ffmpeg's own default-stream heuristic would pick. Uses a synthetic fixture with two audio tracks with claps at very different times (3s vs 7s) -- if detection ignored mpv's active track selection, switching mpv to the second track would still incorrectly report the first track's 3s clap instead of the second track's 7s one. This directly tests the bug hypothesis from user report: 'sometimes too early, sometimes too late, by different amounts' -- exactly what you'd see if detection sometimes analyzed the wrong audio track on multi-audio-track files, since a wrong-track clap position is essentially unrelated to the true one (not a small timestamp-math error). """ import sys import time from pathlib import Path from PyQt6.QtWidgets import QApplication sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) import main as app_main ROOT = Path(__file__).resolve().parent.parent CLIP = str(ROOT / "test_media" / "sync_test_MULTITRACK.mp4") def wait_for(predicate, qapp, timeout=20): deadline = time.time() + timeout while not predicate() and time.time() < deadline: qapp.processEvents() time.sleep(0.05) return predicate() def main(): qapp = QApplication(sys.argv) win = app_main.MainWindow() win.show() qapp.processEvents() win._load(CLIP) qapp.processEvents() time.sleep(0.3) qapp.processEvents() mpv = win.source_panel.player.mpv print(f"default aid: {mpv.aid}") default_index = win._current_audio_stream_index() print(f"resolved ff-index for default track: {default_index}") assert default_index == 1, f"expected default track's ff-index to be 1, got {default_index}" win.detect_all_button.click() qapp.processEvents() ok = wait_for(lambda: win.detect_all_button.isEnabled(), qapp) assert ok, "detection did not finish in time" markers = win.source_panel.marker_strip.markers() print(f"markers with default track selected: {markers}") assert any(abs(m - 3.0) < 0.5 for m in markers), f"expected a marker near 3.0s (default track's clap): {markers}" assert not any(abs(m - 7.0) < 0.5 for m in markers), f"should not see the OTHER track's 7.0s clap yet: {markers}" # Now switch mpv to the second audio track (aid=2), simulating a file # where the user is listening to a non-default track, and rerun # detection -- it must follow the switch, not keep reporting the first # track's clap. mpv.aid = 2 qapp.processEvents() time.sleep(0.2) switched_index = win._current_audio_stream_index() print(f"resolved ff-index after switching to aid=2: {switched_index}") assert switched_index == 2, f"expected ff-index 2 after switching tracks, got {switched_index}" win.source_panel.marker_strip.clear() win.detect_all_button.click() qapp.processEvents() ok = wait_for(lambda: win.detect_all_button.isEnabled(), qapp) assert ok, "detection did not finish in time" markers = win.source_panel.marker_strip.markers() print(f"markers with second track selected: {markers}") assert any(abs(m - 7.0) < 0.5 for m in markers), f"expected a marker near 7.0s (second track's clap) after switching: {markers}" assert not any(abs(m - 3.0) < 0.5 for m in markers), f"should not see the FIRST track's 3.0s clap after switching: {markers}" win.close() qapp.processEvents() print("\nPASS: clap detection follows mpv's actual selected audio track, not ffmpeg's default") if __name__ == "__main__": main()