Commit Graph
650 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 5231852443 Bump version to 0.4.0 (from 0.3.0) for release
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.4.0
2026-10-08 10:01:39 -04:00
207b179428 README Downloads: where to get it first, then builds with Windows before macOS (#271)
Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:50:42 -04:00
86a531ad22 Release: FreeBSD, Flatpak (x86_64 + aarch64) and AppImage zsync; README Downloads (#267)
- release.yml: new `flatpak` jobs (x86_64 on ubuntu-24.04, aarch64 on ubuntu-24.04-arm) that
  repackage the Linux tarball as filmcraft-<v>-linux-<arch>.flatpak, and a `freebsd` job that
  builds filmcraft-<v>-freebsd-x86_64.tar.gz in a FreeBSD 14.3 VM; both feed the draft release.
- AppImages embed gh-releases-zsync update information and ship a .zsync beside them; the
  Linux job checks both.
- Jobs that sign nothing (version, Linux, Flatpak, FreeBSD, web) no longer use the `release`
  environment, so a dispatch on a branch dry-runs them; the signing jobs and the draft-release
  job stay in the environment, so nothing is published from a branch.
- packaging/linux/flatpak-bundle.sh + bundle manifest (same runtime and finish-args as the
  Flathub manifest; packaging-lint checks they agree), packaging/freebsd/package.sh (with a
  --dry-run that packaging-lint runs), and a nightly FreeBSD build workflow.
- README: Downloads section listing every build; docs/releasing.md updated.

Co-authored-by: Brandon Thomas <shared2@storyteller.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:41:42 -04:00
Brandon ThomasandClaude Opus 5.5 08735f3103 Bump version to 0.3.0 (from 0.2.1) for release
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 08:12:49 -04:00
Brandon ThomasandClaude Opus 5.5 61238bf8fc Release CI: macOS job on macos-15-xlarge
Custom macOS larger runners in a runner group do not pick up jobs; the
built-in M2 Pro label does. Only release.yml uses it, and the
actions_macos_xl budget caps the monthly spend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:07:57 -04:00
Brandon ThomasandClaude Opus 5.5 08b769a92a Release CI: macOS job on the org macos-release runner
The standard macOS runners are shared with all CI and queue for an hour or
more. The macos-release runner (GitHub-hosted M2 Pro) is in a runner group
usable only by release.yml on the release branch, with a monthly spend cap
on the actions_macos_xl SKU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:54:54 -04:00
Brandon Thomas 5812509d3b Merge pull request #213 from carlitosteso3/fix/speed-dialog-undo-201
Speed/Duration opens its dialog; dragging an effect parameter is one undo step (#201)
2026-10-07 21:25:58 -04:00
Brandon ThomasandClaude Opus 5.5 ee8f886332 #201: each press of a drag begins its own undo step
A drag value changes only once the mouse moves, after the press frame, so sending `begin`
only on the press frame merged two drags of the same parameter into one undo step.
Remember the press that began a step by its start time instead; unit test drives two drags
through `run` with a real egui context (fails on the press-frame version).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:25:44 -04:00
carlitosteso3andClaude Opus 5.5 70aa661586 #201: Speed/Duration opens its dialog; dragging an effect parameter is one undo step
- The clip menu's Speed/Duration… applied 50% at once, and Cmd+R / Clip ▸
  Speed/Duration… ran it at 100% with no dialog. It now opens Clip Speed /
  Duration (speed, the resulting duration, Reverse Speed, Ripple Edit, Time
  Interpolation), seeded from the selected clip.
- effects.setParam took one undo step per frame of a drag, so Undo after
  dragging Time Remapping's speed (or any Effect Controls value) crept back in
  small steps. It takes `merge` / `begin` like the mixer and masks, and Effect
  Controls sends them while the mouse button is down: a drag is one step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:25:44 -04:00
Brandon ThomasandClaude Opus 5.5 87c4d1516e About: contributor and model credits compiled in (grab bag + table, self-submitted names) (#215)
* About: contributors compiled in from contributors.json (grab bag + table, sortable, name toggle)

Help ▸ About FilmCraft gets tabs About · Contributors · Models, following the craftrules standard
(standards/contributors.md): contributors/contributors.json is generated by
craftrules/scripts/contributors.py and baked into the binary by crates/ui-egui/build.rs as static
tables (nothing read at run time; the web build has them too). Each contributor line: @username,
opt-in display/real name, PRs, commits, lines +/−/Δ, binary assets +/−, first/last commit.
Sortable by every column; alphabetical ignores case and the leading @. Tabs and credits controls
register automation ids (about.tab.*, about.credits.*).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors docs: craftrules is two levels up (../../craftrules)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: self-submitted names in contributors/people.toml; AGENTS.md credit-yourself section

build.rs reads contributors/people.toml next to the generated contributors.json and shows a name only
for entries the generator verified as written by that person (craftrules standards/contributors.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: regenerate (verified people.toml entries)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:16:52 -04:00
Brandon Thomas c337dcce01 Merge pull request #210 from cirocueto2013-wq/fix/hostile-input-bounds
fix: validate hostile project, export and MXF inputs
2026-10-07 20:53:11 -04:00
Brandon ThomasandClaude Opus 5.5 de70468ab6 #210 review: bound MXF reads by the file, keep legacy projects opening, allow 16K
- mxf: read_pcm bounds a request by the sample frames the file actually stores (plus 16M
  samples of zero padding) instead of a fixed 16,777,216-sample cap, so whole-clip reads of
  long stereo MXF (transcription) work again; PCM/AES3 chunk buffers are clamped to the source
  length instead of a 256 MiB cap; decode_pcm's output is bounded by its input, so its
  fixed cap goes (the AES3 >8-channel refusal stays; a request is also bounded by the source
  length divided by the channel count). read_sample keeps only the source-length bound.
- mxf: index_entries no longer fails open() past 1,048,576 entries (the sparse BTreeMap
  already bounds memory by real entries); long recordings open.
- project/format: new Sequence/Track/CaptionTrack::check_bounds() hold only the hostile-value
  bounds (settings, marks, overflowing time ranges); project load and export ranges use it, so
  projects that break only structural rules (overlap, zero duration) still open and export.
  check() = check_bounds() + the structural rules, as before.
- project: frame-size cap raised to 268,435,456 pixels, 32768 per side (16K, 16384x8192).
- engine: checked_u32_p accepts integer-valued floats (1920.0); renderable_sequence returns
  an EngineError (new Session::try_render_program_at, used by automation render) instead of
  eprintln.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:52:53 -04:00
cirocueto2013-wqandCodex 07d85b0f02 fix: validate hostile project, export and MXF inputs
Validate staged speed edits before adopting their timeline state.

Co-authored-by: Codex <noreply@openai.com>
2026-10-07 20:38:43 -04:00
Brandon Thomas a847671dbb Merge pull request #212 from storytold/test-188
#188: regression test — a copied Graphic clip pastes at the playhead
2026-10-07 20:37:34 -04:00
c57541674d #188: regression test — a copied Graphic clip pastes at the playhead
Engine test from #205 (the shortcut half of that PR is superseded by #204).

Co-Authored-By: carlitosteso3 <carlitosteso3@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:36:21 -04:00
5ee3ff64e9 Web: Link Media Locate… links the chosen file to the selected missing clip (#111) (#174)
* Web: Link Media Locate… links the chosen file to the selected missing clip (#111)

Link Media ▸ Locate…, `media.attachProxies` and `media.reconnectFullRes` all
need the chosen file's path back synchronously so they can call the engine
with `item` + `path`. The existing `pick_files` hook imports every chosen
file as a new project item, so on the web build (where the browser picker is
asynchronous and the hook returned `Vec::new()`) the command ran without a
path and the file silently landed as a new project item instead of being
relinked. On native the same hook worked because rfd returns paths
synchronously.

Add a separate `pick_file_for_relink` hook that returns the chosen file's
virtual path synchronously. Native hosts open an rfd dialog; the web host
registers the file in `/files/<name>` via a pending slot and runs
`media.relink` itself when the picker resolves. The three call sites prefer
the new hook and fall back to `pick_files` when the host has not installed
it (so the import flow used by every other dialog stays unchanged).

Fixes #111

Co-Authored-By: ninso112 <ninso112@pm.me>

* Co-ship: Luna161 ack'd and reviewed fix/111-link-media-locate

Reviewed the pick_file_for_relink hook routing, the take_files relink path,
and the regression test. Looks correct end to end; ready for upstream review.

Co-Authored-By: ninso112 <ninso112@pm.me>

* #111: relink hint names its command; no pending state after a cancelled picker

- RelinkHint carries the command (media.relink / attachProxies / reconnectFullRes), so the
  web host no longer runs media.relink for Attach Proxies and Reconnect Full Resolution.
- The web picker hands the hint to its own callback instead of a thread-local slot, so a
  cancelled picker can't turn the next ordinary import into a relink.
- Replace the hook-only unit tests with a UI test that drives Link Media ▸ Locate….

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: ninso112 <ninso112@pm.me>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:35:58 -04:00
Brandon Thomas 4f98721cab Merge pull request #209 from cirocueto2013-wq/fix/cpal-voiceover-recovery
fix: support integer CPAL devices and recover voice-over/audio failures
2026-10-07 20:35:54 -04:00
Brandon Thomas a4d65d3263 Merge pull request #204 from DWAA1660/fix/199-clipboard-shortcuts
#199: make Ctrl+C / Ctrl+X / Ctrl+V work on Windows and Linux
2026-10-07 20:35:50 -04:00
Brandon Thomas 6d904c1b37 Merge pull request #192 from cirocueto2013-wq/fix/editing-workflow-stability
Stabilize project lifecycle, timeline, audio and export workflows
2026-10-07 20:35:46 -04:00
Brandon Thomas d4ca3594ec Merge pull request #203 from carlitosteso3/fix/ripple-razor-snap-164
Ripple delete names the sync-locked track in the way; playhead snaps to cuts (#164, items 2, 3 and snap)
2026-10-07 20:35:42 -04:00
Brandon Thomas cd7395ec7c Merge pull request #207 from carlitosteso3/fix/ripple-trim-targets-164
Q/W ripple trim only the selected clips' tracks (#164)
2026-10-07 20:35:37 -04:00
carlitosteso3andClaude Opus 5.5 41659ae769 #164: Q/W ripple trim only the selected clips' tracks
With clips selected under the playhead, Ripple Trim Previous/Next Edit to
Playhead (and the plain trims) now trim only their tracks and linked partners,
like Add Edit; with none selected they use the targeted tracks as before. All
tracks are targeted by default, so W on a V1 clip also cut the music on A2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 18:50:39 -05:00
carlitosteso3andClaude Opus 5.5 e7e96b247f #164: ripple delete says which sync-locked track blocks it; playhead snaps to cuts
- A refused ripple delete / ripple trim now names the sync-locked track whose
  clip is in the way and how to proceed, instead of a generic "would break sync"
  (the edit is refused the same way Premiere refuses it).
- Dragging the playhead no longer snaps onto its own position (it stuck and moved
  in SNAP_PX jumps), snaps on the initial press too, and "Snap playhead in
  Timeline when Snap is enabled" is on by default, as in Premiere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 18:47:21 -05:00
cirocueto2013-wqandCodex 7151d329d6 fix: support integer CPAL devices and recover voice-over/audio failures
Co-authored-by: Codex <noreply@openai.com>
2026-10-07 20:33:33 -03:00
DWAA1660andClaude Opus 5.5 f4221cd1b5 #199: make Ctrl+C / Ctrl+X / Ctrl+V work on Windows and Linux
egui-winit reports the clipboard shortcuts as Event::Copy / Cut / Paste
instead of key presses, so the shortcut bindings never matched them.
Outside text fields, add the key press each clipboard event stands for
before matching bindings, and put copied clip names on the system
clipboard so Ctrl+V is delivered right after a copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QQNunPf8nMeAQi6M92RT68
2026-10-07 16:57:38 -06:00
cirocueto2013-wqandCodex 1fd30aa29d engine: bound subclip media resolution and reject cycles
Co-authored-by: Codex <noreply@openai.com>
2026-10-07 19:56:58 -03:00
Brandon Thomas a4536bcfed Merge pull request #180 from SaymonMaster14/feat/windows-nvenc-h264
Windows: NVENC H.264 hardware encoding for Export (opt-in)
2026-10-07 18:17:05 -04:00
Brandon ThomasandClaude Opus 5.5 853f03b1aa M-HW: NVENC on top of the shared hardware-encoding setting (#183); never-crash fixes
Merge origin/main into the NVENC branch. #183 already provides the
HardwareEncoding enum, ExportSettings.hardware_encoding, the
hardwareEncoding export param and the Export > Video > Hardware Encoding
checkbox, so the duplicates from this branch are dropped and NVENC uses
them. filmcraft-export is now an all-platform dependency of
filmcraft-platform (VideoToolbox and NVENC both register encoders).

Never-crash fixes in the NVENC backend:
- submit() rejects a driver input pitch narrower than a row (and unlocks
  the buffer); fill_nv12 uses get_mut instead of slicing rows.
- composition offsets use saturating math and i32::try_from; frame-rate,
  size and timestamp casts are checked; sizes above u16::MAX decline.
- Annex B scanning and NAL type checks use get()/first().
- A failed nvEncOpenEncodeSessionEx that returns a handle destroys it.

ffi.rs carries NVIDIA's MIT notice for nvEncodeAPI.h, listed in
ATTRIBUTION.md under a new "Third-party source code" section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 18:16:12 -04:00
Brandon Thomas 71483312b6 Merge pull request #162 from SaymonMaster14/feat/windows-vp9-av1-hwdecode
Windows: VP9 + AV1 hardware decode (Media Foundation / DXVA)

# Conflicts:
#	ROADMAP.md
#	crates/platform/README.md
2026-10-07 17:58:12 -04:00
Brandon Thomas 13f71e3111 Merge pull request #175 from Luna161/fix/110-import-refreshes-offline
Engine: file.import refreshes the offline-missing list (#110)
2026-10-07 17:56:50 -04:00
Brandon ThomasandClaude Opus 5.5 4e4efcef12 M-relink: file.import also drops the cached slate of media it brought back (#110)
refresh() cleared the Missing badge, but the media pool kept the
MEDIA NOT FOUND slate cached under the item, so the monitors kept
showing it. The regression test now checks the rendered frame too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:56:33 -04:00
Brandon Thomas a4b92f1bec Merge remote-tracking branch 'origin/main' into pr-175 2026-10-07 17:54:19 -04:00
Brandon Thomas 1fe80344c7 Merge pull request #195 from midasdf/fix/vertical-type-tool-flyout
M10: choose vertical titles from the Type tool flyout
2026-10-07 17:53:53 -04:00
Brandon ThomasandClaude Opus 5.5 bd5387dff6 Merge main into #195: vertical type on top of point/paragraph text (#166)
The Type-tool click now goes through new_text_action; Vertical Type swaps
in graphics.newVerticalText and never draws a paragraph box (vertical text
is point text). Drops the dated ROADMAP log line (the maintainers keep the log).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:53:45 -04:00
Brandon ThomasandClaude Opus 5.5 6ce2038a00 M-HW: keep the Windows-only annexb/biplanar helpers warning-free on other systems (#141)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 17:50:20 -04:00
Brandon Thomas fcf1c45583 Merge pull request #141 from SaymonMaster14/feat/windows-media-foundation-hwdecode
Windows: Media Foundation/D3D11 hardware H.264 + HEVC decode

# Conflicts:
#	README.md
#	ROADMAP.md
#	crates/platform/Cargo.toml
#	crates/platform/src/lib.rs
#	docs/architecture.md
#	docs/performance.md
2026-10-07 17:48:06 -04:00
Brandon Thomas b5f197567b Merge pull request #186 from dcarnelutti/platform/videotoolbox-hevc-encode
platform: H.265 (HEVC) export with VideoToolbox

# Conflicts:
#	crates/export/src/settings_tests.rs
#	crates/ui-egui/tests/export_ui.rs
2026-10-07 17:47:10 -04:00
Brandon Thomas 84fcbeb1b9 Merge pull request #183 from dcarnelutti/platform/videotoolbox-h264-encode
platform: opt-in hardware H.264 encoding with VideoToolbox

# Conflicts:
#	crates/engine/src/export_tests.rs
2026-10-07 17:46:57 -04:00
Brandon Thomas d18bc04023 Merge pull request #184 from dcarnelutti/render/overlay-bounds-and-buffer-reuse
render: composite only what overlays cover, and reuse the float images
2026-10-07 17:46:38 -04:00
Brandon Thomas fed7201fcf Merge pull request #185 from dcarnelutti/export/progress-eta
export: show the estimated time left of a render next to its percentage
2026-10-07 17:46:37 -04:00
Brandon Thomas cbf181bd1f Merge pull request #176 from RicSchonfelder/i18n-pt-br
i18n: add Brazilian Portuguese (pt-br) UI translation
2026-10-07 17:46:33 -04:00
Brandon Thomas ce5d365c78 Merge pull request #165 from carlitosteso3/fix/media-browser-probe-157
Media Browser: probing a file doesn't read it whole (#157)

# Conflicts:
#	crates/engine/src/media_pool.rs
2026-10-07 17:46:32 -04:00
Brandon Thomas d01e1b893d Merge pull request #145 from carlitosteso3/fix/color-matte-29
Color Matte: pick the color on creation and change it later (#29)
2026-10-07 17:46:23 -04:00
Brandon Thomas c86847ff72 Merge pull request #155 from carlitosteso3/fix/playback-stalled-audio-136
Playback: a stalled audio device no longer freezes the playhead (#136)
2026-10-07 17:46:22 -04:00
Brandon Thomas 0810b403ce Merge pull request #148 from EthanSuquet/fix/h264-rc-slow-start
h264enc: 1-pass bitrate modes no longer starve the opening second
2026-10-07 17:46:21 -04:00
Brandon Thomas 8b3f118878 Merge pull request #173 from carlitosteso3/fix/shortcut-modifiers-164
Shortcut recorder accepts modifier chords; Add Edit cuts only selected clips (#164, items 1 and 5)
2026-10-07 17:46:20 -04:00
Brandon Thomas b4c65bdf8a Merge pull request #189 from Luna161/fix/168-project-select-all
Engine: project.selectAll and project.deselectAll for the Project panel (#168)
2026-10-07 17:46:19 -04:00
Brandon Thomas 47f75df15e Merge pull request #182 from justjohn12345/pr/layer-box-visibility
Graphics: only selected layers have a box, and a hidden layer has none
2026-10-07 17:44:08 -04:00
Brandon Thomas 91a36a4a3f Merge pull request #166 from justjohn12345/pr/text-box-modes
Graphics: point text and paragraph text, as Premiere has them
2026-10-07 17:44:07 -04:00
Brandon Thomas a3667ad26e Merge pull request #190 from ajsongpilot/fix/new-from-file-anchor
Graphics: New Layer from File anchors the picture at its own centre
2026-10-07 17:44:06 -04:00