from __future__ import annotations import json import subprocess import sys from pathlib import Path from scripts.twitter_archive.decompose_media import build_output_paths, summarize_probe def test_build_output_paths_creates_local_artifact_tree() -> None: paths = build_output_paths("12345", 1) assert paths["clip_dir"].parts[-3:] == ("media", "decomposed", "12345") assert paths["audio_path"].name == "001_audio.wav" assert paths["keyframes_dir"].name == "001_keyframes" assert paths["metadata_path"].name == "001_metadata.json" assert paths["transcript_path"].name == "001_transcript.json" def test_summarize_probe_extracts_duration_resolution_and_stream_flags() -> None: probe = { "format": {"duration": "4.015", "bit_rate": "832000"}, "streams": [ {"codec_type": "video", "width": 320, "height": 240, "avg_frame_rate": "30/1"}, {"codec_type": "audio", "sample_rate": "44100"}, ], } summary = summarize_probe(probe) assert summary["duration_s"] == 4.015 assert summary["video"]["width"] == 320 assert summary["video"]["height"] == 240 assert summary["video"]["fps"] == 30.0 assert summary["audio"]["present"] is True assert summary["audio"]["sample_rate"] == 44100 def test_cli_decomposes_one_local_clip(tmp_path: Path) -> None: clip = tmp_path / "clip.mp4" subprocess.run( [ "ffmpeg", "-y", "-f", "lavfi", "-i", "testsrc=size=160x120:rate=8", "-f", "lavfi", "-i", "sine=frequency=880:sample_rate=16000", "-t", "2", "-pix_fmt", "yuv420p", str(clip), ], capture_output=True, check=True, ) out_dir = tmp_path / "out" result = subprocess.run( [ sys.executable, "-m", "scripts.twitter_archive.decompose_media", "--input", str(clip), "--tweet-id", "999", "--media-index", "1", "--output-root", str(out_dir), ], capture_output=True, text=True, check=True, ) payload = json.loads(result.stdout) assert payload["status"] == "ok" assert Path(payload["metadata_path"]).exists() assert Path(payload["audio_path"]).exists() assert Path(payload["keyframes_dir"]).exists() assert list(Path(payload["keyframes_dir"]).glob("*.jpg"))