Fixing various bugs relating to building the event lsit
This commit is contained in:
@@ -4520,6 +4520,23 @@ def cmd_render(
|
||||
|
||||
# Check for unaligned markers
|
||||
unaligned = [t for t in marker_timings if t.timestamp < 0]
|
||||
if slide_range and unaligned:
|
||||
# Partial (--slides) render: only unaligned markers INSIDE the requested
|
||||
# range should block it — failures elsewhere in the manuscript are
|
||||
# irrelevant to this window. Restrict to the manuscript-order span
|
||||
# [start_slide, end_slide].
|
||||
order = [t.marker_id for t in marker_timings]
|
||||
start_slide, end_slide = slide_range
|
||||
lo = order.index(start_slide) if start_slide in order else 0
|
||||
hi = order.index(end_slide) if (end_slide and end_slide in order) else len(order) - 1
|
||||
in_range = set(order[lo : hi + 1])
|
||||
skipped = [t for t in unaligned if t.marker_id not in in_range]
|
||||
unaligned = [t for t in unaligned if t.marker_id in in_range]
|
||||
if skipped:
|
||||
print(
|
||||
f"\n ({len(skipped)} unaligned marker(s) outside the {start_slide}:"
|
||||
f"{end_slide or ''} range ignored for this partial render)"
|
||||
)
|
||||
if unaligned:
|
||||
print(f"\n WARNING: {len(unaligned)} marker(s) could not be aligned!")
|
||||
for t in unaligned:
|
||||
|
||||
@@ -476,6 +476,7 @@ def parse_videos(
|
||||
|
||||
videos = {}
|
||||
for video_id, video_data in data.items():
|
||||
|
||||
if "source_file" not in video_data:
|
||||
raise ParseError(
|
||||
f"Video '{video_id}' missing required field 'source_file'", videos_path
|
||||
|
||||
+26
-5
@@ -806,7 +806,7 @@ def preprocess_video(
|
||||
filter_type=first_filter_type,
|
||||
)
|
||||
|
||||
# If output_file is specified, copy/rename to final location and clean up
|
||||
# If output_file is specified, move/copy to final location and clean up
|
||||
if video_source.output_file:
|
||||
import shutil
|
||||
|
||||
@@ -814,11 +814,32 @@ def preprocess_video(
|
||||
|
||||
final_output.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Write to a .tmp file first so that an interrupted copy never leaves a
|
||||
# partial file at the final path (which would be silently skipped next run).
|
||||
# Stage on a .tmp on the destination filesystem, then atomically swap in —
|
||||
# an interrupted transfer never leaves a partial file at the final path.
|
||||
tmp_output = final_output.with_suffix(".tmp")
|
||||
shutil.copy2(current_input, tmp_output)
|
||||
tmp_output.replace(final_output) # atomic on same filesystem
|
||||
|
||||
# current_input is the last batch's scratch intermediate (about to be
|
||||
# deleted anyway), so MOVE it into place rather than copying — concat has
|
||||
# already written this multi-GB ProRes once, and a rename is instant on the
|
||||
# same filesystem. Only fall back to a copy across filesystems (e.g. scratch
|
||||
# on an external SSD, output on the internal disk). Never move the original
|
||||
# source (transcribe-only path leaves current_input == source).
|
||||
moved = False
|
||||
if current_input in intermediate_files:
|
||||
try:
|
||||
os.replace(current_input, tmp_output)
|
||||
moved = True
|
||||
except OSError:
|
||||
moved = False # cross-filesystem — copy instead
|
||||
if not moved:
|
||||
try:
|
||||
size_gb = current_input.stat().st_size / (1024**3)
|
||||
print(f" Finalizing: copying {size_gb:.1f} GB to output (cross-disk)...")
|
||||
except OSError:
|
||||
pass
|
||||
shutil.copy2(current_input, tmp_output)
|
||||
|
||||
os.replace(tmp_output, final_output) # atomic on the destination filesystem
|
||||
|
||||
if verbose:
|
||||
print(f" Final output: {final_output}")
|
||||
|
||||
Reference in New Issue
Block a user