40 Commits

Author SHA1 Message Date
Ethanfel 7d7172e531 Add frame interpolation (frame doubling) to Export with Transitions
New post-export step that multiplies the frame count by interpolating
between every consecutive frame pair. Supports 2x/4x/8x multipliers
using RIFE, FILM, or BiM-VFI methods.

- Add frame interpolation checkbox, multiplier combo (2x/4x/8x), and
  method combo (RIFE/FILM/BiM-VFI) to Export Options group
- Implement _frame_interpolation_pass: works in log2(multiplier) passes,
  each pass doubles frames by inserting midpoint interpolations
- Uses _fi_ temp prefix during rename to avoid filename collisions
- Preserves per-file extensions for mixed-format sequences
- Handles cancellation gracefully (renames temp files back)
- Runs after transition export, before optional video encoding
- Also clean up leftover _fi_ temp files in orphan removal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:26:48 +01:00
Ethanfel 6b7d9b969b Fix export range, progress bar, blend params, and temp file cleanup
- Fix _sequence_frame_count excluding direct interpolation frames,
  which caused export range max to be too small and truncate output
- Fix blend_images call missing optical flow parameters (of_levels,
  of_winsize, of_iterations, of_poly_n, of_poly_sigma) — optical
  flow blends in transition export used defaults instead of user config
- Fix progress bar not reaching 100% when direct interpolation is
  used — current_op was never incremented for generated frames
- Fix BiM-VFI temp files (bimvfi_temp_*.png) not cleaned up by
  orphan removal in manager.py
- Update "+" row text to say "AI transition" instead of "RIFE/FILM"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:17:55 +01:00
Ethanfel 3d654efcfd Fix image deletion not persisting and autosave session accumulation
- Fix _delete_current_image: delegate to _remove_selected_files so
  deletions are tracked in _removed_files / trim adjustments and
  survive _refresh_files calls and session save/restore
- Fix _auto_save_session: reuse _current_session_id when available
  instead of always creating new sessions. Clean up old autosave
  sessions for the same destination to prevent unbounded accumulation.
- Fix signal cascade in _on_destination_changed: blockSignals around
  _add_to_path_history to prevent currentIndexChanged re-entry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:08:05 +01:00
Ethanfel 2db0cbb76a Fix BiM-VFI integration bugs from code review
- Fix critical import: use `from modules.components import make_components`
  instead of `from modules.components.components` so the @register
  decorator fires and the model can be instantiated
- Use separate venv (venv-bimvfi) to avoid dependency conflicts with
  RIFE/FILM — basicsr-fixed/cupy/lpips can break the shared venv
- BimVfiEnv now creates its own venv with PyTorch, independent of RIFE
- Remove dead code: dis0/dis1/scale_factor/ratio/nr_lvl_skipped kwargs
  are silently ignored by model's **kwargs, and get_scale_factor/
  get_pyr_level were computing unused values
- Use model's trained pyr_level=3 (set at construction) instead of
  overriding to 5-7 at inference which was untested
- Use `python -m pip` and `python -m gdown` instead of direct binaries
  for cross-platform reliability
- Add checkpoint size validation (>1MB) on download
- Verify torch importable in is_setup() instead of just checking files
- Update UI: BiM-VFI setup flow is independent, doesn't need RIFE first

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:57:27 +01:00
Ethanfel 67422302da Add BiM-VFI as interpolation method for direct transitions
Integrate KAIST VICLab's BiM-VFI (CVPR 2025) as a third option
alongside RIFE and FILM for AI frame interpolation between sequences.

- Add BIM_VFI enum value to DirectInterpolationMethod
- Create core/bim_vfi_worker.py subprocess worker following FILM pattern
- Add BimVfiEnv class managing repo clone, deps install, and checkpoint
  download (via gdown from Google Drive)
- Add batch and single-frame dispatch in TransitionGenerator
- Add bim_vfi_blend() to ImageBlender with FILM fallback
- Update DirectTransitionDialog UI with BiM-VFI option and setup flow

BiM-VFI setup auto-clones the repo, installs deps (cupy, basicsr-fixed,
etc.) into the shared PyTorch venv, and downloads the checkpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:35:54 +01:00
Ethanfel 546e93ceb1 Fix multiple bugs from code analysis rounds
- Fix RIFE warp() grid cache: move backwarp_tenGrid to module level so it persists across calls
- Fix FILM partial download: download to .tmp file then atomically rename, validate file size
- Fix fid_to_pos orphan fallthrough: use .get(fid) with None check instead of defaulting to 0
- Fix commonpath ValueError: guard against mixed-drive paths on Windows
- Fix ON CONFLICT clause in direct_transition_settings to match UNIQUE constraint
- Remove dead save_folder_type_override method from database
- Fix subprocess resource leaks in video.py: add try/except/kill around proc loops
- Fix concat file handle leak: wrap writes in try/finally
- Fix format conversion in transition export: normalize extension comparison
- Fix session restore loop: blockSignals during destination path changes
- Fix missing folder handling: keep as placeholders instead of skipping
- Fix fid=0 skip guard in _restore_files_from_session

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:31:27 +01:00
Ethanfel a6461a2ce8 Handle missing source folders gracefully with placeholder display
Missing folders now show in red with (MISSING) tag instead of silently
disappearing. Auto-save always persists session settings (folder order,
trims, transitions) even when folders are missing, so the session
layout survives for later replacement via right-click > Replace Folder.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:34:11 +01:00
Ethanfel 7c2acd326f Fix file list not updating when folder type changes
_set_folder_type was missing a _refresh_files() call, so changing a
folder between TRANSITION and MAIN didn't rebuild the file list until
a manual reorder.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:14:31 +01:00
Ethanfel 30911e894a Sync file removal with trim slider for edge selections
Removing files contiguous from the start/end of a sequence now adjusts
the trim handles instead of tracking them as individual removals, so
dragging the slider back restores them. Middle removals still tracked
separately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:55:45 +01:00
Ethanfel dd426b958b Fix trim label not reflecting removed files count
The trim label now shows removed file count alongside trim range,
e.g. "Frames 1-81 of 81 (78 included, 3 removed)" instead of
always showing the full disk count.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:49:07 +01:00
Ethanfel 8dda4f56a0 Add session lock feature and fix format conversion in transition export
- Add locked column to sessions with toggle in restore dialog, preventing
  accidental deletion of important sessions (padlock icon, DB-level protection)
- Fix transition export copying source files as-is when output format differs
  (e.g. webp sources now convert to png when png format is selected)
- Fix ON CONFLICT clause in save_per_transition_settings to match UNIQUE constraint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:05:31 +01:00
Ethanfel 793ba4243d Add cleanup unused videos feature to remove unreferenced video folders
Adds right-click context menu on empty source list space with "Cleanup Unused Videos..."
option that scans type_of_video/ directories for video folders not in the current session,
showing a dialog with checkboxes to delete or move them to .trash/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 12:36:10 +01:00
Ethanfel 15c00e5fd2 Fix transition overlap duplicates, trim slider sync, and drag performance
- Make each transition boundary symmetric (left_overlap controls MAIN→TRANS,
  right_overlap controls TRANS→MAIN) so frame indices map 1:1 with no repeats
- Track committed frames per folder to cap overlaps and prevent over-allocation
- Fix float truncation in frame mapping (int→round) that caused off-by-one dupes
- Sync trim slider to follow frame selection in Sequence Order / With Transitions
- Defer expensive file list rebuild to mouse release for smooth trim slider drag
- Apply trim settings to transition folders in both display and export paths
- Refresh trim slider after session restore to show correct file counts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:18:50 +01:00
Ethanfel 2694a8cba3 Add split/merge sequence feature with fid-based folder tracking
Refactor folder settings from path-keyed to fid-keyed dicts so the same
physical folder can appear multiple times with independent trim, type,
and transition settings.  This enables splitting a MAIN folder into two
sub-sequences at an arbitrary frame boundary using complementary trim
ranges, and merging them back.

- Add split from file list context menu ("Split Sequence After This
  Frame") and source list context menu ("Split Sequence..." dialog)
- Add "Merge with Next" to undo splits on adjacent same-path entries
- Sub-sequences share the base sequence number (seq01-1, seq01-2) with
  continuous file indices so subsequent sequences are not renumbered
- Session save/restore handles duplicate paths via folder_order; restore
  falls back to _refresh_files when split entries are detected
- Export copy_matches now compares file contents when size matches but
  mtime differs, preventing false negatives on re-export

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 23:27:13 +01:00
Ethanfel 6e2d6148af Fix OF preset default, content splitter drag lag, and sequence table column resize
- Stop restoring OF preset from session so widget default (Max) always applies
- Add minimum widths and size policies to content_splitter children
- Change sequence_table Main Frame column from Stretch to Interactive

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:22:10 +01:00
Ethanfel 2599265410 Fix splitter drag acceleration by removing stretch factors
setStretchFactor on QSplitter interferes with manual handle dragging —
Qt applies stretch redistribution after each mouse move, compounding
the delta and creating an accelerating effect. Replaced with size
policies (Expanding on right panel) which achieve the same window-
resize behavior without fighting the splitter drag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:14:32 +01:00
Ethanfel 1de641d756 Fix timeline seconds label overlapping frame number column
The right-side time label was drawn at the viewport edge, overlapping
the # column when frame numbers had 3+ digits. Now drawn at the right
edge of column 1 (before the # column starts).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:11:46 +01:00
Ethanfel 9f4b1e17f6 Prevent splitter panels from collapsing to zero
Both splitters now have setChildrenCollapsible(False) so neither side
can be dragged to zero width. Right panel gets minWidth 400 to stay
usable when the source panel is expanded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:08:36 +01:00
Ethanfel cd8878c91b Fix source panel splitter drag: remove maxWidth clamp, widen handles
The source panel had maxWidth(400) which barely let the splitter move
beyond its starting position. Removed the cap, lowered minWidth from
250 to 150, and widened both splitter handles to 5px for easier grab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:06:35 +01:00
Ethanfel f706328e4d Fix column resize: switch from ResizeToContents to Interactive
ResizeToContents columns can't be dragged — they snap back to their
computed width, making resize attempts feel broken. Changed to
Interactive mode with explicit initial widths and minimum section
size so columns are freely draggable while still having sensible
defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:04:22 +01:00
Ethanfel 893132f110 Add multi-select delete to Restore Session dialog
- Session list now supports extended selection (Shift+click for range,
  Ctrl+click for individual)
- "Delete Selected" button removes chosen sessions with confirmation
- List refreshes in-place after deletion so you can keep cleaning up
- Added delete_sessions() batch method to database (single transaction)
- Simplified delete_session() to rely on ON DELETE CASCADE

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:55:37 +01:00
Ethanfel 00e393f7b9 Fix export crash: batch DB inserts and let event loop breathe
The export loop was opening a new DB connection per file AND starving
the Qt event loop, causing the progress bar to freeze then jump and
the app to crash during large copy exports.

Fixes:
- All record_symlink calls in both export paths now collect records
  and batch-insert in a single transaction at the end
- Added explicit QApplication.processEvents() in export loops
- Throttled progress label updates to every 10 files (text rendering
  was adding overhead on every iteration)
- Moved shutil import out of inner loops

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:53:09 +01:00
Ethanfel 2c4778e598 Add Replace Folder option to preserve edits when swapping a clip
Right-click any folder in the source list → "Replace Folder..." opens
a file dialog. The new folder takes the old one's position and inherits
all settings: type override, trim, per-transition overlap, removed
files, and direct transition config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 12:56:01 +01:00
Ethanfel 0efc6e153f Fix session save freeze and restore losing removed files
Save freeze fix:
- Added record_symlinks_batch() that inserts all symlinks in a single
  DB transaction instead of opening a new connection per file
- _save_session and _auto_save_session now use batch inserts
- With 1700 files this goes from 1700 connection cycles to 1

Removed files fix:
- _restore_files_from_session now filters by _removed_files so
  individually deleted files stay removed even when restoring from
  session data that pre-dates the removal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 12:06:01 +01:00
Ethanfel c03ee0665b Fix session save/restore losing folders, add frame column and UI improvements
Session restore fixes:
- AUTO-typed folders now default to MAIN on restore instead of using
  position-based index%2, which silently flipped half the folders to
  TRANSITION when restoring legacy sessions
- All restored folders get explicit type overrides so no folder relies
  on position-based typing after restore
- TRANSITION folders with symlink data are auto-recovered as MAIN
  (catches incorrectly saved types from older export paths)
- Export Sequence path now saves with save_effective_types=True,
  preventing folder type loss
- Removed redundant trim-only save that used unresolved paths
- Auto-save guards against overwriting sessions with empty file lists

UI improvements:
- Added 4th "Frame" column to Sequence Order tab showing overall
  frame number (1-based)
- Last frame of each sequence is bold for visual clarity
- Fixed column resizing (ResizeToContents + Stretch) to prevent
  column collapse bugs
- Save Session dialog now reports main + transition folder counts
- Default optical flow preset changed to Max

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 11:55:48 +01:00
Ethanfel 82a1c2ff9f Fix export range, transition frame counting, session restore, and video encoding
- Fix export range not covering TRANSITION folder middle frames: range max
  was based on MAIN-only file count, causing blends at sequence end to be
  silently skipped. Now uses full sequence frame count from preview table.
- Fix preview table not counting TRANSITION middle frames: these frames are
  output as symlinks in export but were shown without sequence numbers in
  preview. Now displayed as [T] entries with proper output_seq numbering.
- Fix session restore path resolution: all folder paths now .resolve()'d on
  save and restored with _resolve_lookup() fallback for both raw and resolved
  forms. Fixes folder order corruption on restore.
- Fix legacy session restore: detect pre-migration sessions (all folder_order=0)
  and fall back to symlink-derived ordering with get_all_folder_settings().
- Fix ffmpeg concat demuxer duration format: use decimal instead of fraction.
- Fix QProgressDialog false cancellation from autoReset at max value.
- Fix Export with Transitions skipping TRANSITION folders entirely while
  preview processed them, causing cutoff at blend boundaries.
- Fix Encode Video Only not finding transition-exported files in trans_dest.
- Add video encoding module (core/video.py) with concat demuxer support.
- Add direct_transition_settings DB table and persistence.
- Add sticky folder types on reorder and placeholder transition slots.
- Add blend-skipped-range counter to export completion dialog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 01:35:59 +01:00
Ethanfel 78a1c8b795 Robust export with progress bar, file removal persistence, copy mode
- Rewrite _export_sequence with QProgressDialog, per-file error handling,
  cancel support, and continuous seq_00000 naming
- Add folder progress labels to _process_with_transitions
- Extend cleanup_old_links to remove film_temp_*.png temporaries
- Add copy-files checkbox for Docker/remote destinations
- Persist individually removed files across sessions (removed_files table)
- Recover file removals from export history for older sessions
- Save effective folder types in transition exports for reliable restore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 21:13:49 +01:00
Ethanfel 5defd664ed film 2026-02-05 14:59:03 +01:00
Ethanfel e58dc27dce Make FILM the default for direct interpolation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 11:55:06 +01:00
Ethanfel fb67ad5683 flow 2026-02-03 23:58:00 +01:00
Ethanfel 8c1de543d3 doc 2026-02-03 23:31:41 +01:00
Ethanfel d26265a115 rife 2026-02-03 23:26:07 +01:00
Ethanfel 00f0141b15 rife 2026-02-03 23:21:31 +01:00
Ethanfel 2c6ad4ff35 Add Practical-RIFE frame interpolation support
Implement standalone PyTorch-based RIFE interpolation that runs in a
dedicated virtual environment to avoid Qt/OpenCV conflicts:

- Add PracticalRifeEnv class for managing venv and subprocess execution
- Add rife_worker.py standalone interpolation script using Practical-RIFE
- Add RIFE_PRACTICAL blending model with ensemble/fast mode settings
- Add UI controls for Practical-RIFE configuration
- Update .gitignore to exclude venv-rife/ directory

The implementation downloads Practical-RIFE models on first use and runs
interpolation in a separate process with proper progress reporting.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:46:06 +01:00
Ethanfel 6bfbefb058 Update README with comprehensive feature documentation
- Document cross-dissolve transitions and blend methods
- Add RIFE auto-download instructions
- Document per-folder trim and per-transition overlap
- Add file structure diagram
- Update installation requirements
- Expand supported formats list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:51:50 +01:00
Ethanfel bdddce910c Restructure into multi-file architecture
Split monolithic symlink.py into modular components:
- config.py: Constants and configuration
- core/: Models, database, blender, manager
- ui/: Main window and widgets

New features included:
- Cross-dissolve transitions with multiple blend methods
- Alpha blend, Optical Flow, and RIFE (AI) interpolation
- Per-folder trim settings with start/end frame control
- Per-transition asymmetric overlap settings
- Folder type overrides (Main/Transition)
- Dual destination folders (sequence + transitions)
- WebP lossless output with compression method setting
- Video and image sequence preview with zoom/pan
- Session resume from destination folder

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:49:51 +01:00
Ethanfel 99858bcfe8 Add alternating row colors to source folder list
Improves readability of the source folder panel.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:49:39 +01:00
Ethanfel 716ff34062 cool 2026-02-03 16:21:56 +01:00
Ethanfel 5c43caa75f Add README with feature documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 10:30:39 +01:00
Ethanfel ee77a43322 Initial commit: Video Montage Linker
PyQt6 application to create sequenced symlinks for image files.

Features:
- GUI and CLI modes
- Multiple source folder support with drag & drop
- SQLite database for tracking symlink sessions
- Multi-select and reorder files
- Two-column file view (filename + source path)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 10:29:11 +01:00