60 lines
2.3 KiB
Python
60 lines
2.3 KiB
Python
"""Plain Python checks, including real FFmpeg encoding when installed."""
|
|
import binascii
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import struct
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
import zlib
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "Content/Python"))
|
|
from ue_workshop.paths import slug
|
|
from ue_workshop.video import encode
|
|
|
|
|
|
def png(path, rgb):
|
|
def chunk(kind, data):
|
|
return struct.pack(">I", len(data)) + kind + data + struct.pack(">I", binascii.crc32(kind + data) & 0xffffffff)
|
|
path.write_bytes(b"\x89PNG\r\n\x1a\n" +
|
|
chunk(b"IHDR", struct.pack(">IIBBBBB", 4, 4, 8, 2, 0, 0, 0)) +
|
|
chunk(b"IDAT", zlib.compress((b"\x00" + bytes(rgb) * 4) * 4)) + chunk(b"IEND", b""))
|
|
|
|
|
|
class OfflineTests(unittest.TestCase):
|
|
def test_generated_asset_name_cannot_escape_folder(self):
|
|
for value in ["../Outside", "A/B", "", "A.B", "0Shot", "A B"]:
|
|
with self.subTest(value=value), self.assertRaises(ValueError):
|
|
slug(value)
|
|
self.assertEqual(slug("MyShot_2"), "MyShot_2")
|
|
|
|
def test_missing_frames_are_rejected_before_encoding(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
folder = Path(directory)
|
|
png(folder / "frame_0001.png", (255, 0, 0))
|
|
with self.assertRaisesRegex(RuntimeError, "numeracji"):
|
|
encode(folder, 24)
|
|
|
|
def test_incomplete_render_is_not_encoded(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
folder = Path(directory)
|
|
png(folder / "frame_0000.png", (255, 0, 0))
|
|
with self.assertRaisesRegex(RuntimeError, "zamiast 2"):
|
|
encode(folder, 24, expected_frames=2)
|
|
|
|
@unittest.skipUnless(shutil.which("ffmpeg") or os.environ.get("WORKSHOP_FFMPEG"), "FFmpeg missing")
|
|
def test_real_mp4_encoding(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
folder = Path(directory) / "frames"
|
|
folder.mkdir()
|
|
png(folder / "frame_0000.png", (255, 0, 0))
|
|
png(folder / "frame_0001.png", (0, 0, 255))
|
|
movie = encode(folder, 24, expected_frames=2)
|
|
self.assertGreater(movie.stat().st_size, 100)
|
|
self.assertIn(b"ftyp", movie.read_bytes()[:32])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|