"""Unit tests for the ffmpeg muxer. Requires ``ffmpeg`` on PATH. On Windows, if ffmpeg is not installed these tests are skipped (they will run inside the Docker image where ffmpeg is always present). """ import os import shutil import struct import numpy as np import pytest from server.video_models.muxer import frames_and_audio_to_mp4, frames_to_mp4_loop pytestmark = pytest.mark.skipif( shutil.which("ffmpeg") is None, reason="ffmpeg not installed locally; run these inside Docker", ) def _rgb_frames(t, h=64, w=64): """Coloured checker frames so the encoder has real content.""" frames = np.zeros((t, h, w, 3), dtype=np.uint8) for i in range(t): frames[i, :, :, 0] = (i * 20) % 255 frames[i, :h // 2, :, 1] = 255 frames[i, :, :w // 2, 2] = 255 return frames def test_frames_to_mp4_loop_produces_mp4_bytes(): frames = _rgb_frames(8) data = frames_to_mp4_loop(frames, fps=16) assert isinstance(data, bytes) assert len(data) > 0 # MP4 files start with an ftyp box: 4 bytes size + 'ftyp' assert data[4:8] == b"ftyp" def test_frames_and_audio_to_mp4_produces_mp4_bytes(): frames = _rgb_frames(16) # 1s silent audio at 24kHz audio = np.zeros(24000, dtype=np.float32) data = frames_and_audio_to_mp4(frames, audio, sample_rate=24000, fps=16) assert isinstance(data, bytes) assert len(data) > 0 assert data[4:8] == b"ftyp" def test_frames_to_mp4_loop_rejects_empty(): with pytest.raises(ValueError): frames_to_mp4_loop(np.empty((0, 64, 64, 3), dtype=np.uint8), fps=16) def test_frames_and_audio_to_mp4_rejects_empty_audio(): frames = _rgb_frames(4) with pytest.raises(ValueError): frames_and_audio_to_mp4( frames, np.empty(0, dtype=np.float32), sample_rate=24000, fps=16 ) def test_frames_to_mp4_loop_rejects_wrong_shape(): with pytest.raises(ValueError): frames_to_mp4_loop(np.zeros((4, 64, 64), dtype=np.uint8), fps=16)