68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
import shutil
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
|
|
|
from frame_sampler import FrameSampler, calculate_timestamps
|
|
from scratch_manager import ScratchManager
|
|
|
|
|
|
class Story03SamplingTests(unittest.TestCase):
|
|
def test_calculate_timestamps_uses_uniform_temporal_spacing(self):
|
|
stamps = calculate_timestamps(duration=90.0, interval=30.0)
|
|
self.assertEqual(stamps, [0.0, 30.0, 60.0])
|
|
|
|
def test_frame_sampler_builds_ffmpeg_command_with_scale_and_jpeg_output(self):
|
|
sampler = FrameSampler(interval_seconds=30, quality=2, output_format="jpeg")
|
|
command = sampler._build_ffmpeg_command(
|
|
video_path="/tmp/video.mp4",
|
|
output_path="/tmp/out.jpg",
|
|
timestamp=12.5,
|
|
resolution=(3840, 2160),
|
|
)
|
|
|
|
self.assertIn("ffmpeg", command[0])
|
|
self.assertIn("-ss", command)
|
|
self.assertIn("-vframes", command)
|
|
self.assertIn("scale=1920:1080", " ".join(command))
|
|
self.assertTrue(command[-1].endswith("out.jpg"))
|
|
|
|
def test_frame_sampler_uses_subprocess_and_returns_output_path(self):
|
|
sampler = FrameSampler(interval_seconds=30, quality=2, output_format="jpeg")
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
video_path = Path(tmpdir) / "sample.mp4"
|
|
output_path = Path(tmpdir) / "frame.jpg"
|
|
video_path.write_bytes(b"fake")
|
|
|
|
def _mock_run(*args, **kwargs):
|
|
output_path.write_bytes(b"frame")
|
|
return type("Completed", (), {"returncode": 0, "stdout": b"", "stderr": b""})()
|
|
|
|
with patch("subprocess.run", side_effect=_mock_run):
|
|
result = sampler.extract_frame(
|
|
video_path=str(video_path),
|
|
output_path=str(output_path),
|
|
timestamp=15.0,
|
|
resolution=(1280, 720),
|
|
)
|
|
|
|
self.assertTrue(result)
|
|
self.assertEqual(output_path.name, Path(result).name)
|
|
|
|
def test_scratch_manager_cleans_up_frames_after_processing(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
manager = ScratchManager(base_path=tmpdir, video_id="video-1", auto_cleanup=True)
|
|
frame_dir = manager.ensure_frame_dir()
|
|
(frame_dir / "video-1_1000.jpg").write_bytes(b"frame")
|
|
|
|
manager.cleanup()
|
|
self.assertFalse(frame_dir.exists())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|