Fix intro title fade toggle
This commit is contained in:
parent
4a61a3100b
commit
37dccfb28c
2 changed files with 50 additions and 12 deletions
|
|
@ -39,11 +39,11 @@ DEFAULT_INTRO_LOGO = BASE_DIR / "img" / "moto_travel.png"
|
||||||
INTRO_LOGO_TARGET_HEIGHT_RATIO = 0.75
|
INTRO_LOGO_TARGET_HEIGHT_RATIO = 0.75
|
||||||
INTRO_LOGO_EXTRA_HOLD = 6.0
|
INTRO_LOGO_EXTRA_HOLD = 6.0
|
||||||
INTRO_LOGO_FADE_OFFSET = 3.0
|
INTRO_LOGO_FADE_OFFSET = 3.0
|
||||||
INTRO_LOGO_DEFAULT_ALPHA = 1.0
|
INTRO_LOGO_DEFAULT_ALPHA = 0.75
|
||||||
INTRO_TITLE_START_OFFSET = 4.0
|
INTRO_TITLE_START_OFFSET = 0.0
|
||||||
INTRO_TITLE_FADE_LENGTH = 1.0
|
INTRO_TITLE_FADE_LENGTH = 1.0
|
||||||
INTRO_TITLE_VISIBLE = 6.0
|
INTRO_TITLE_VISIBLE = 6.0
|
||||||
INTRO_TITLE_FADE_ENABLED = True
|
INTRO_TITLE_FADE_IN_ENABLED = False
|
||||||
DEFAULT_IMAGE_DURATION = 6.0
|
DEFAULT_IMAGE_DURATION = 6.0
|
||||||
DEFAULT_CROSSFADE_DURATION = 3.0
|
DEFAULT_CROSSFADE_DURATION = 3.0
|
||||||
FIRST_IMAGE_DURATION_MULTIPLIER = 2.0
|
FIRST_IMAGE_DURATION_MULTIPLIER = 2.0
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,9 @@ def list_jobs(host: str, remote_root: str) -> list[str]:
|
||||||
return [line.strip() for line in out.splitlines() if line.strip()]
|
return [line.strip() for line in out.splitlines() if line.strip()]
|
||||||
|
|
||||||
|
|
||||||
def remote_file_exists(host: str, path: str) -> bool:
|
def remote_file_exists(host: str | None, path: str) -> bool:
|
||||||
|
if host is None:
|
||||||
|
return Path(path).is_file()
|
||||||
return ssh(host, f"test -f {remote_q(path)}", check=False).returncode == 0
|
return ssh(host, f"test -f {remote_q(path)}", check=False).returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -92,7 +94,13 @@ print(hashlib.sha256(json.dumps(entries, ensure_ascii=False, separators=(',', ':
|
||||||
return ssh(host, cmd).stdout.strip()
|
return ssh(host, cmd).stdout.strip()
|
||||||
|
|
||||||
|
|
||||||
def read_remote_json(host: str, path: str) -> dict:
|
def read_remote_json(host: str | None, path: str) -> dict:
|
||||||
|
if host is None:
|
||||||
|
try:
|
||||||
|
data = json.loads(Path(path).read_text(encoding="utf-8"))
|
||||||
|
return data if isinstance(data, dict) else {}
|
||||||
|
except Exception:
|
||||||
|
return {}
|
||||||
res = ssh(host, f"cat {remote_q(path)} 2>/dev/null", check=False)
|
res = ssh(host, f"cat {remote_q(path)} 2>/dev/null", check=False)
|
||||||
if res.returncode != 0 or not res.stdout.strip():
|
if res.returncode != 0 or not res.stdout.strip():
|
||||||
return {}
|
return {}
|
||||||
|
|
@ -115,11 +123,24 @@ def write_remote_json(host: str, path: str, data: dict) -> None:
|
||||||
ssh(host, cmd, input_text=payload)
|
ssh(host, cmd, input_text=payload)
|
||||||
|
|
||||||
|
|
||||||
def read_state(host: str, job_dir: str) -> dict:
|
def read_state(host: str | None, job_dir: str) -> dict:
|
||||||
|
if host is None:
|
||||||
|
path = Path(job_dir) / STATE_NAME
|
||||||
|
if not path.exists():
|
||||||
|
return {}
|
||||||
|
try:
|
||||||
|
return json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except Exception:
|
||||||
|
return {}
|
||||||
return read_remote_json(host, f"{job_dir}/{STATE_NAME}")
|
return read_remote_json(host, f"{job_dir}/{STATE_NAME}")
|
||||||
|
|
||||||
|
|
||||||
|
def write_state(host: str | None, job_dir: str, state: dict) -> None:
|
||||||
def write_state(host: str, job_dir: str, state: dict) -> None:
|
if host is None:
|
||||||
|
path = Path(job_dir) / STATE_NAME
|
||||||
|
path.write_text(json.dumps(state, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||||
|
path.chmod(0o664)
|
||||||
|
return
|
||||||
path = f"{job_dir}/{STATE_NAME}"
|
path = f"{job_dir}/{STATE_NAME}"
|
||||||
tmp_path = f"{path}.tmp.$$"
|
tmp_path = f"{path}.tmp.$$"
|
||||||
data = json.dumps(state, ensure_ascii=False, indent=2) + "\n"
|
data = json.dumps(state, ensure_ascii=False, indent=2) + "\n"
|
||||||
|
|
@ -129,7 +150,7 @@ def write_state(host: str, job_dir: str, state: dict) -> None:
|
||||||
f"mv {remote_q(tmp_path)} {remote_q(path)}"
|
f"mv {remote_q(tmp_path)} {remote_q(path)}"
|
||||||
)
|
)
|
||||||
ssh(host, cmd, input_text=data)
|
ssh(host, cmd, input_text=data)
|
||||||
|
|
||||||
|
|
||||||
def copy_job_from_remote(host: str, job_dir: str, local_input: Path) -> None:
|
def copy_job_from_remote(host: str, job_dir: str, local_input: Path) -> None:
|
||||||
local_input.mkdir(parents=True, exist_ok=True)
|
local_input.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
@ -215,7 +236,23 @@ def render_job(local_input: Path, local_out: Path, extra_args: list[str]) -> Pat
|
||||||
"--intro-logo-alpha", INTRO_LOGO_ALPHA,
|
"--intro-logo-alpha", INTRO_LOGO_ALPHA,
|
||||||
]
|
]
|
||||||
cmd = [sys.executable, str(MOVMAKER), str(local_input), "--out-dir", str(local_out), *intro_args, *extra_args]
|
cmd = [sys.executable, str(MOVMAKER), str(local_input), "--out-dir", str(local_out), *intro_args, *extra_args]
|
||||||
subprocess.run(cmd, check=True)
|
log_dir = local_input / ".logs"
|
||||||
|
log_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
log_path = log_dir / f"mvlog_worker_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
|
||||||
|
try:
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
|
||||||
|
except subprocess.CalledProcessError as exc:
|
||||||
|
log_path.write_text(
|
||||||
|
"Command failed:\n" + " ".join(cmd) + "\n\nSTDOUT:\n" + (exc.stdout or "") + "\n\nSTDERR:\n" + (exc.stderr or ""),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
raise RuntimeError(f"movmaker failed; see {log_path}") from exc
|
||||||
|
else:
|
||||||
|
if result.stdout or result.stderr:
|
||||||
|
log_path.write_text(
|
||||||
|
"Command:\n" + " ".join(cmd) + "\n\nSTDOUT:\n" + (result.stdout or "") + "\n\nSTDERR:\n" + (result.stderr or ""),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
outputs = sorted(local_out.glob("*.mp4"), key=lambda p: p.stat().st_mtime, reverse=True)
|
outputs = sorted(local_out.glob("*.mp4"), key=lambda p: p.stat().st_mtime, reverse=True)
|
||||||
if not outputs:
|
if not outputs:
|
||||||
raise RuntimeError("movmaker finished but no MP4 was produced")
|
raise RuntimeError("movmaker finished but no MP4 was produced")
|
||||||
|
|
@ -338,6 +375,7 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
parser = argparse.ArgumentParser(description="Render changed MVLog input dirs from a remote web server.")
|
parser = argparse.ArgumentParser(description="Render changed MVLog input dirs from a remote web server.")
|
||||||
|
parser.add_argument("--local", action="store_true", help="Treat remote paths as local; skip SSH")
|
||||||
parser.add_argument("--host", default="192.168.0.204", help="SSH host for the web server")
|
parser.add_argument("--host", default="192.168.0.204", help="SSH host for the web server")
|
||||||
parser.add_argument("--remote-root", default="/var/www/html/mvlog", help="Remote MVLog web root")
|
parser.add_argument("--remote-root", default="/var/www/html/mvlog", help="Remote MVLog web root")
|
||||||
parser.add_argument("--work-dir", default=str(Path.home() / ".cache" / "mvlog-worker"), help="Local work directory")
|
parser.add_argument("--work-dir", default=str(Path.home() / ".cache" / "mvlog-worker"), help="Local work directory")
|
||||||
|
|
@ -348,9 +386,9 @@ def main() -> int:
|
||||||
|
|
||||||
work_dir = Path(args.work_dir)
|
work_dir = Path(args.work_dir)
|
||||||
work_dir.mkdir(parents=True, exist_ok=True)
|
work_dir.mkdir(parents=True, exist_ok=True)
|
||||||
jobs = args.job or list_jobs(args.host, args.remote_root)
|
jobs = args.job or list_jobs(None if args.local else args.host, args.remote_root)
|
||||||
for job in jobs:
|
for job in jobs:
|
||||||
process_job(args.host, args.remote_root, job, work_dir, args.movmaker_arg, args.force)
|
process_job(None if args.local else args.host, args.remote_root, job, work_dir, args.movmaker_arg, args.force)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue