mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-15 13:36:35 +03:00
Adds evidence-bounded video and podcast editing references, reusable templates, deterministic media workflow helpers, and tests. Closes #438.
55 lines
2.6 KiB
Python
Executable File
55 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Compare two ffprobe JSON documents against basic media criteria."""
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def load(path):
|
|
try:
|
|
return json.loads(Path(path).read_text(encoding="utf-8"))
|
|
except (OSError, json.JSONDecodeError) as exc:
|
|
raise ValueError(str(exc)) from exc
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("input_probe")
|
|
parser.add_argument("output_probe")
|
|
parser.add_argument("--duration-tolerance", type=float, default=0.1)
|
|
parser.add_argument("--require-subtitles", action="store_true")
|
|
args = parser.parse_args()
|
|
try:
|
|
before = load(args.input_probe)
|
|
after = load(args.output_probe)
|
|
except ValueError as exc:
|
|
print(json.dumps({"ok": False, "status": "invalid_probe", "error": str(exc)}))
|
|
return 2
|
|
before_streams = before.get("streams", [])
|
|
after_streams = after.get("streams", [])
|
|
checks = [{"criterion": "output_has_streams", "passed": bool(after_streams)}]
|
|
for stream_type in ("video", "audio"):
|
|
before_stream = next((s for s in before_streams if s.get("codec_type") == stream_type), None)
|
|
after_stream = next((s for s in after_streams if s.get("codec_type") == stream_type), None)
|
|
if before_stream:
|
|
checks.append({"criterion": f"{stream_type}_stream", "passed": after_stream is not None})
|
|
if after_stream and before_stream.get("codec_name") and after_stream.get("codec_name"):
|
|
checks.append({"criterion": f"{stream_type}_codec", "passed": before_stream["codec_name"] == after_stream["codec_name"], "input": before_stream["codec_name"], "output": after_stream["codec_name"]})
|
|
if args.require_subtitles:
|
|
checks.append({"criterion": "subtitle_stream", "passed": any(s.get("codec_type") == "subtitle" for s in after_streams)})
|
|
try:
|
|
input_duration = float(before.get("format", {}).get("duration"))
|
|
output_duration = float(after.get("format", {}).get("duration"))
|
|
except (TypeError, ValueError):
|
|
input_duration = output_duration = None
|
|
if input_duration is not None and output_duration is not None:
|
|
checks.append({"criterion": "duration", "passed": abs(input_duration - output_duration) <= args.duration_tolerance, "input": input_duration, "output": output_duration, "tolerance": args.duration_tolerance})
|
|
ok = all(check["passed"] for check in checks)
|
|
print(json.dumps({"ok": ok, "status": "pass" if ok else "fail", "checks": checks}, indent=2, sort_keys=True))
|
|
return 0 if ok else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|