fix(skill): preserve GIF palette and paths

This commit is contained in:
Tianyi Cui
2026-07-23 17:18:18 +08:00
parent f7103c833c
commit c02eb6d941

View File

@@ -114,11 +114,11 @@ def stream_int(stream: dict[str, object], key: str, path: Path) -> int:
def ffconcat_quote(path: Path) -> str: def ffconcat_quote(path: Path) -> str:
"""Quote an absolute path for the ffconcat file directive.""" """Quote an ffconcat path while preserving literal backslashes."""
value = str(path) value = str(path)
if "\n" in value or "\r" in value: if "\n" in value or "\r" in value:
fail(f"frame path contains a newline: {path}") fail(f"frame path contains a newline: {path}")
return "'" + value.replace("\\", "\\\\").replace("'", "'\\''") + "'" return "'" + value.replace("'", "'\\''") + "'"
def write_concat_manifest(path: Path, frames: list[Path], durations: list[float]) -> None: def write_concat_manifest(path: Path, frames: list[Path], durations: list[float]) -> None:
@@ -153,7 +153,7 @@ def build_parser() -> argparse.ArgumentParser:
"--colors", "--colors",
type=positive_int, type=positive_int,
default=128, default=128,
help="palette colors, from 2 through 256", help="palette colors, from 4 through 256",
) )
parser.add_argument( parser.add_argument(
"--max-bytes", "--max-bytes",
@@ -177,8 +177,8 @@ def main() -> None:
fail(f"output must end in .gif: {output}") fail(f"output must end in .gif: {output}")
if output.exists() and not args.force: if output.exists() and not args.force:
fail(f"output already exists (pass --force to replace it): {output}") fail(f"output already exists (pass --force to replace it): {output}")
if not 2 <= args.colors <= 256: if not 4 <= args.colors <= 256:
fail("--colors must be between 2 and 256") fail("--colors must be between 4 and 256")
if args.fps > 30: if args.fps > 30:
fail("--fps must not exceed 30") fail("--fps must not exceed 30")
@@ -206,7 +206,7 @@ def main() -> None:
manifest = Path(temporary) / "frames.ffconcat" manifest = Path(temporary) / "frames.ffconcat"
write_concat_manifest(manifest, frames, durations) write_concat_manifest(manifest, frames, durations)
scale = f"scale='min({args.max_width},iw)':-2:flags=lanczos" scale = f"scale='min({args.max_width},iw)':-2:flags=lanczos"
palette = f"palettegen=max_colors={args.colors}:stats_mode=diff" palette = f"palettegen=max_colors={args.colors}:stats_mode=full"
filters = ( filters = (
f"fps={args.fps},{scale},split[base][palette_input];" f"fps={args.fps},{scale},split[base][palette_input];"
f"[palette_input]{palette}[palette];" f"[palette_input]{palette}[palette];"