Re-record the panorama for the trained filler; the scene waits for the preview and for the DNG instead of guessing
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -21,6 +21,7 @@ shift || true
|
|||||||
export DR_HOME="${DR_HOME:-/var/tmp/dr-manual}"
|
export DR_HOME="${DR_HOME:-/var/tmp/dr-manual}"
|
||||||
export DR_DISPLAY="${DR_DISPLAY:-:7}"
|
export DR_DISPLAY="${DR_DISPLAY:-:7}"
|
||||||
export DR_BIN="${DR_BIN:-$repo/target/release/darkroom-desktop}"
|
export DR_BIN="${DR_BIN:-$repo/target/release/darkroom-desktop}"
|
||||||
|
export DR_LIBRARY="$library"
|
||||||
media="$repo/docs/manual/media"
|
media="$repo/docs/manual/media"
|
||||||
mkdir -p "$media" "$DR_HOME/xdg/config/darkroom" "$DR_HOME/xdg/data/darkroom"
|
mkdir -p "$media" "$DR_HOME/xdg/config/darkroom" "$DR_HOME/xdg/data/darkroom"
|
||||||
|
|
||||||
|
|||||||
+65
-3
@@ -11,6 +11,8 @@ scene, so a different library needs the numbers looked at again. Panel
|
|||||||
coordinates hold for any library.
|
coordinates hold for any library.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -18,6 +20,7 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|||||||
import drive as dr # noqa: E402
|
import drive as dr # noqa: E402
|
||||||
|
|
||||||
OUT = sys.argv[1] if len(sys.argv) > 1 else '.'
|
OUT = sys.argv[1] if len(sys.argv) > 1 else '.'
|
||||||
|
DEMO_LIBRARY = os.environ.get('DR_LIBRARY', '') # the folder the merge writes its DNG into
|
||||||
|
|
||||||
|
|
||||||
def shot(name):
|
def shot(name):
|
||||||
@@ -130,6 +133,9 @@ def library_thumbsize():
|
|||||||
|
|
||||||
|
|
||||||
def library_selection():
|
def library_selection():
|
||||||
|
# The grid remembers its scroll between launches; the cells below are
|
||||||
|
# the grid at its top.
|
||||||
|
wheel(-40, 900, 500); pause(0.6)
|
||||||
dr.click(*SELECT); pause(0.5)
|
dr.click(*SELECT); pause(0.5)
|
||||||
dr.click(*CELL_PANO_FIRST); pause(0.3)
|
dr.click(*CELL_PANO_FIRST); pause(0.3)
|
||||||
dr.x('keydown', 'shift'); dr.click(*CELL_NY_LAST); dr.x('keyup', 'shift'); pause(0.8)
|
dr.x('keydown', 'shift'); dr.click(*CELL_NY_LAST); dr.x('keyup', 'shift'); pause(0.8)
|
||||||
@@ -322,14 +328,70 @@ def develop_export():
|
|||||||
|
|
||||||
|
|
||||||
# --- panorama ---------------------------------------------------------------
|
# --- panorama ---------------------------------------------------------------
|
||||||
|
def wait_for_new(folder, suffix, since, timeout):
|
||||||
|
"""Until a file ending in `suffix` newer than `since` appears in
|
||||||
|
`folder`'s tree — the merge's DNG — or `timeout` seconds pass."""
|
||||||
|
t0 = time.time()
|
||||||
|
while time.time() - t0 < timeout:
|
||||||
|
for root, _, files in os.walk(folder):
|
||||||
|
for f in files:
|
||||||
|
if f.lower().endswith(suffix) and os.path.getmtime(os.path.join(root, f)) > since:
|
||||||
|
return True
|
||||||
|
time.sleep(2)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def wait_until_lit(px, py, timeout):
|
||||||
|
"""Until the window pixel at (px, py) is no longer black — the fill
|
||||||
|
preview has reached the corner of the border — or `timeout` passes."""
|
||||||
|
t0 = time.time()
|
||||||
|
while time.time() - t0 < timeout:
|
||||||
|
out = subprocess.run(
|
||||||
|
['import', '-window', dr.win(), '-crop', f'1x1+{px}+{py}', '-depth', '8', 'txt:-'],
|
||||||
|
capture_output=True, text=True).stdout
|
||||||
|
m = re.search(r'\((\d+),(\d+),(\d+)', out)
|
||||||
|
if m and max(int(v) for v in m.groups()) > 24:
|
||||||
|
return True
|
||||||
|
time.sleep(3)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def join(name, parts):
|
||||||
|
"""Concatenate recorded clips into `name`.mp4 and drop the parts."""
|
||||||
|
lst = f'{OUT}/{name}.txt'
|
||||||
|
with open(lst, 'w') as f:
|
||||||
|
for p in parts:
|
||||||
|
f.write(f"file '{OUT}/{p}.mp4'\n")
|
||||||
|
subprocess.run(['ffmpeg', '-hide_banner', '-loglevel', 'error', '-y', '-f', 'concat', '-safe', '0',
|
||||||
|
'-i', lst, '-c', 'copy', f'{OUT}/{name}.mp4'], check=True)
|
||||||
|
os.remove(lst)
|
||||||
|
for p in parts:
|
||||||
|
os.remove(f'{OUT}/{p}.mp4')
|
||||||
|
|
||||||
|
|
||||||
def panorama():
|
def panorama():
|
||||||
to_library()
|
to_library()
|
||||||
library_selection()
|
library_selection()
|
||||||
rec('panorama')
|
rec('panorama-a')
|
||||||
dr.click(1325, 1079); pause(40) # Merge to panorama
|
dr.click(1325, 1079); pause(40) # Merge to panorama
|
||||||
dr.click(184, 637); pause(45) # Fill the border
|
shot('panorama-aligned')
|
||||||
dr.click(1543, 22); pause(60) # Merge
|
dr.click(184, 637); pause(6) # Fill the border
|
||||||
cut()
|
cut()
|
||||||
|
# The preview fills at the working scale — minutes on the CPU rung —
|
||||||
|
# so the film pauses until the border's corner has been painted.
|
||||||
|
wait_until_lit(60, 110, 400)
|
||||||
|
pause(3)
|
||||||
|
shot('panorama-filled')
|
||||||
|
rec('panorama-b')
|
||||||
|
pause(2)
|
||||||
|
started = time.time()
|
||||||
|
dr.click(1543, 22); pause(8) # Merge
|
||||||
|
cut()
|
||||||
|
join('panorama', ['panorama-a', 'panorama-b'])
|
||||||
|
# The merge itself takes minutes too; the last picture is the
|
||||||
|
# composite in the grid.
|
||||||
|
wait_for_new(DEMO_LIBRARY, '.dng', started, 600) if DEMO_LIBRARY else pause(60)
|
||||||
|
pause(5)
|
||||||
shot('panorama-done')
|
shot('panorama-done')
|
||||||
dr.click(*BACK); pause(2)
|
dr.click(*BACK); pause(2)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user