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
|
# Check for unaligned markers
|
||||||
unaligned = [t for t in marker_timings if t.timestamp < 0]
|
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:
|
if unaligned:
|
||||||
print(f"\n WARNING: {len(unaligned)} marker(s) could not be aligned!")
|
print(f"\n WARNING: {len(unaligned)} marker(s) could not be aligned!")
|
||||||
for t in unaligned:
|
for t in unaligned:
|
||||||
|
|||||||
+2
-1
@@ -476,11 +476,12 @@ def parse_videos(
|
|||||||
|
|
||||||
videos = {}
|
videos = {}
|
||||||
for video_id, video_data in data.items():
|
for video_id, video_data in data.items():
|
||||||
|
|
||||||
if "source_file" not in video_data:
|
if "source_file" not in video_data:
|
||||||
raise ParseError(
|
raise ParseError(
|
||||||
f"Video '{video_id}' missing required field 'source_file'", videos_path
|
f"Video '{video_id}' missing required field 'source_file'", videos_path
|
||||||
)
|
)
|
||||||
|
|
||||||
# Parse attribution if present
|
# Parse attribution if present
|
||||||
attribution = None
|
attribution = None
|
||||||
if "attribution" in video_data:
|
if "attribution" in video_data:
|
||||||
|
|||||||
+26
-5
@@ -806,7 +806,7 @@ def preprocess_video(
|
|||||||
filter_type=first_filter_type,
|
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:
|
if video_source.output_file:
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
@@ -814,11 +814,32 @@ def preprocess_video(
|
|||||||
|
|
||||||
final_output.parent.mkdir(parents=True, exist_ok=True)
|
final_output.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# Write to a .tmp file first so that an interrupted copy never leaves a
|
# Stage on a .tmp on the destination filesystem, then atomically swap in —
|
||||||
# partial file at the final path (which would be silently skipped next run).
|
# an interrupted transfer never leaves a partial file at the final path.
|
||||||
tmp_output = final_output.with_suffix(".tmp")
|
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:
|
if verbose:
|
||||||
print(f" Final output: {final_output}")
|
print(f" Final output: {final_output}")
|
||||||
|
|||||||
Reference in New Issue
Block a user