Version 1 OneShot

This commit is contained in:
2026-10-09 18:58:50 +00:00
parent 514c13d184
commit bf0d661eed
27 changed files with 3039 additions and 0 deletions

75
tests/test_integration.py Normal file
View File

@@ -0,0 +1,75 @@
"""End-to-end tests against a real ffmpeg. Skipped when ffmpeg is not available.
Set FFWRAP_FFMPEG_DIR to point at a folder containing ffmpeg/ffprobe, or put them on PATH.
"""
import os
import subprocess
from pathlib import Path
import pytest
from ffwrap.command import Options, build_command, match_audio_selection
from ffwrap.probe import probe
from ffwrap.tools import locate_tools
TOOLS = locate_tools(os.environ.get("FFWRAP_FFMPEG_DIR"))
pytestmark = pytest.mark.skipif(TOOLS is None, reason="ffmpeg/ffprobe not found")
@pytest.fixture(scope="module")
def sample(tmp_path_factory) -> Path:
"""3 s 640x360 H.264 + jpn 5.1 AC3 + eng stereo AAC + English SRT in an MKV."""
d = tmp_path_factory.mktemp("media")
srt = d / "subs.srt"
srt.write_text("1\n00:00:00,500 --> 00:00:02,000\nHello\n", encoding="utf-8")
out = d / "sample.mkv"
subprocess.run([
TOOLS.ffmpeg, "-v", "error", "-y",
"-f", "lavfi", "-i", "testsrc2=size=640x360:rate=25:duration=3",
"-f", "lavfi", "-i", "sine=frequency=440:duration=3",
"-f", "lavfi", "-i", "sine=frequency=880:duration=3",
"-i", str(srt),
"-map", "0", "-map", "1", "-map", "2", "-map", "3",
"-c:v", "libx264", "-preset", "ultrafast",
"-c:a:0", "ac3", "-ac:a:0", "6", "-c:a:1", "aac", "-ac:a:1", "2", "-c:s", "srt",
"-metadata:s:a:0", "language=jpn", "-metadata:s:a:1", "language=eng",
"-metadata:s:s:0", "language=eng",
str(out),
], check=True)
return out
def run(info, opts, audio, out):
built = build_command(TOOLS.ffmpeg, info, opts, audio, out)
res = subprocess.run(built.args, capture_output=True, text=True)
assert res.returncode == 0, res.stderr
return probe(TOOLS.ffprobe, out)
def test_remux_to_mp4_keeps_streams(sample, tmp_path):
info = probe(TOOLS.ffprobe, sample)
eng = match_audio_selection(info.audio, [info.audio[1].index], info.audio)
out = run(info, Options(container="mp4"), eng, tmp_path / "out.mp4")
assert out.video.codec == "h264"
assert [(a.codec, a.language) for a in out.audio] == [("aac", "eng")]
assert [s.codec for s in out.subtitles] == ["mov_text"]
assert abs(out.duration - info.duration) < 0.5
def test_reencode_scale_and_downmix(sample, tmp_path):
info = probe(TOOLS.ffprobe, sample)
opts = Options(container="mkv", video_mode="encode", video_encoder="libx265", resolution=240,
speed=0, audio_mode="encode", audio_encoder="libopus", audio_channels=2, subtitles=False)
out = run(info, opts, [a.index for a in info.audio], tmp_path / "out.mkv")
assert out.video.codec == "hevc" and (out.video.width, out.video.height) == (426, 240)
assert [(a.codec, a.channels) for a in out.audio] == [("opus", 2), ("opus", 2)]
assert out.subtitles == []
def test_strip_audio_webm(sample, tmp_path):
info = probe(TOOLS.ffprobe, sample)
opts = Options(container="webm", video_mode="auto", video_encoder="libvpx-vp9", speed=0, audio_mode="strip")
out = run(info, opts, [], tmp_path / "out.webm")
assert out.video.codec == "vp9" and out.audio == []
assert [s.codec for s in out.subtitles] == ["webvtt"]