90 lines
2.5 KiB
Python
90 lines
2.5 KiB
Python
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"))
|