mvlog_worker: upload audio files to remote in-dir; update README
This commit is contained in:
parent
0183b86031
commit
a7d6a4e1ed
2 changed files with 49 additions and 2 deletions
|
|
@ -164,6 +164,8 @@ The worker:
|
||||||
7. removes the old output if the regenerated filename changed
|
7. removes the old output if the regenerated filename changed
|
||||||
8. clears the web metadata cache
|
8. clears the web metadata cache
|
||||||
|
|
||||||
|
Note: The worker now also uploads audio files found in the local input directory back to the webserver's in-dir (the same job subdirectory) after rendering. It skips files that already exist on the server. Supported extensions include: .mp3, .wav, .m4a, .aac, .flac, .ogg, .opus, .wma, .aiff, .aif. When running against a remote host the worker uploads using scp (upload to a temporary filename then move into place); when run with --local it copies files into the remote path. Audio upload failures are reported as warnings and do not prevent publishing the generated MP4. After successful uploads the worker recomputes the job fingerprint and records it in the job state so subsequent runs avoid unnecessary re-rendering.
|
||||||
|
|
||||||
Run once:
|
Run once:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,39 @@ def publish_output(host: str, remote_root: str, local_mp4: Path, old_output: str
|
||||||
return out_name
|
return out_name
|
||||||
|
|
||||||
|
|
||||||
|
def upload_audio_files(host: str | None, job_dir: str, local_input: Path) -> list[str]:
|
||||||
|
"""Upload audio files found inside local_input to the remote job_dir/in-dir if they are missing.
|
||||||
|
|
||||||
|
Returns a list of uploaded relative paths.
|
||||||
|
"""
|
||||||
|
AUDIO_EXTS = {".mp3", ".wav", ".m4a", ".aac", ".flac", ".ogg", ".opus", ".wma", ".aiff", ".aif"}
|
||||||
|
uploaded: list[str] = []
|
||||||
|
for path in sorted(local_input.rglob("*")):
|
||||||
|
if not path.is_file():
|
||||||
|
continue
|
||||||
|
if path.suffix.lower() not in AUDIO_EXTS:
|
||||||
|
continue
|
||||||
|
rel = path.relative_to(local_input).as_posix()
|
||||||
|
remote_path = f"{job_dir}/{rel}"
|
||||||
|
if remote_file_exists(host, remote_path):
|
||||||
|
print(f"audio exists on server, skipping: {rel}")
|
||||||
|
continue
|
||||||
|
parent = str(Path(remote_path).parent)
|
||||||
|
if host is None:
|
||||||
|
Path(parent).mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.copy2(str(path), remote_path)
|
||||||
|
else:
|
||||||
|
# Ensure parent directory exists on the remote host
|
||||||
|
ssh(host, f"mkdir -p {remote_q(parent)}")
|
||||||
|
remote_tmp = f"{remote_path}.tmp.$$"
|
||||||
|
# Upload to a temporary file then move into place for (some) atomicity
|
||||||
|
subprocess.run(["scp", str(path), f"{host}:{remote_tmp}"], check=True)
|
||||||
|
ssh(host, f"mv {remote_q(remote_tmp)} {remote_q(remote_path)}")
|
||||||
|
uploaded.append(rel)
|
||||||
|
print(f"uploaded audio: {rel}")
|
||||||
|
return uploaded
|
||||||
|
|
||||||
|
|
||||||
def render_job(local_input: Path, local_out: Path, extra_args: list[str]) -> Path:
|
def render_job(local_input: Path, local_out: Path, extra_args: list[str]) -> Path:
|
||||||
local_out.mkdir(parents=True, exist_ok=True)
|
local_out.mkdir(parents=True, exist_ok=True)
|
||||||
intro_logo = INTRO_LOGO if INTRO_LOGO.exists() else None
|
intro_logo = INTRO_LOGO if INTRO_LOGO.exists() else None
|
||||||
|
|
@ -293,11 +326,18 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
|
|
||||||
if preview_mode:
|
if preview_mode:
|
||||||
preview_output = publish_output(host, remote_root, local_mp4, old_preview_output)
|
preview_output = publish_output(host, remote_root, local_mp4, old_preview_output)
|
||||||
|
# Upload any audio files present in the local input directory to the remote in-dir if missing.
|
||||||
|
try:
|
||||||
|
upload_audio_files(host, job_dir, local_input)
|
||||||
|
except Exception as exc: # Upload failure should not prevent publishing the preview
|
||||||
|
print(f"warning: audio upload failed: {exc}")
|
||||||
|
# Recompute fingerprint now that audio files may have been uploaded.
|
||||||
|
final_fingerprint = remote_fingerprint(host, job_dir)
|
||||||
new_state = dict(state)
|
new_state = dict(state)
|
||||||
new_state.update({
|
new_state.update({
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"mode": "preview",
|
"mode": "preview",
|
||||||
"preview_fingerprint": fingerprint_after,
|
"preview_fingerprint": final_fingerprint,
|
||||||
"preview_output": preview_output,
|
"preview_output": preview_output,
|
||||||
"preview_generated_at": now(),
|
"preview_generated_at": now(),
|
||||||
})
|
})
|
||||||
|
|
@ -306,11 +346,16 @@ def process_job(host: str, remote_root: str, job: str, work_dir: Path, extra_arg
|
||||||
return
|
return
|
||||||
|
|
||||||
output = publish_output(host, remote_root, local_mp4, old_output)
|
output = publish_output(host, remote_root, local_mp4, old_output)
|
||||||
|
try:
|
||||||
|
upload_audio_files(host, job_dir, local_input)
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"warning: audio upload failed: {exc}")
|
||||||
|
final_fingerprint = remote_fingerprint(host, job_dir)
|
||||||
new_state = dict(state)
|
new_state = dict(state)
|
||||||
new_state.update({
|
new_state.update({
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"mode": "full",
|
"mode": "full",
|
||||||
"fingerprint": fingerprint_after,
|
"fingerprint": final_fingerprint,
|
||||||
"output": output,
|
"output": output,
|
||||||
"generated_at": now(),
|
"generated_at": now(),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue