Skip to content

Export: duration sources, audio length, scene/BPM metadata, clean cancel (#523, #524, #528, #532) - #762

Merged
CaYatur merged 2 commits into
mainfrom
feat/export-job
Oct 16, 2026
Merged

CaYatur merged 2 commits into
mainfrom
feat/export-job

Conversation

@CaYatur

@CaYatur CaYatur commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Closes #523, #524, #528 and #532.

Duration (#523)

  • Sources. Length of the audio file (the default, unchanged), a fixed number of seconds, the timeline's length (latest clip, marker or loop end), or N bars. Bars use a typed BPM, or the timeline's tempo map when the BPM is 0.
  • Where it is resolved. The main process measures the audio with ffmpeg and resolves the length before starting. The renderer draws ceil(seconds × fps) frames, and frames past the end of the audio are drawn with silence.
  • Empty timeline. It is refused with a reason.

Audio follows the video (#524)

Metadata (#528)

  • File name. The save dialog suggests "Track - Scene - 128 BPM". Characters Windows forbids, reserved names (CON, NUL, COM1…) and trailing dots or spaces are removed, and the name is capped at 150 characters.
  • Inside the file. comment carries Scene: … · BPM: … next to title, artist and album. MP4 and MOV do not write custom keys, and comment is read everywhere.
  • MCP. sceneName is optional and defaults to the active scene. duration is a new argument.

No partial file at the final path (#532)

  • Write, then rename. Output goes to name.partial.ext (folder.partial for a sequence) and is renamed only after ffmpeg exits 0. If the rename fails, the job reports an error and names the partial file instead of losing it.
  • Cancel or error. The partial output is removed. A renderer crash still keeps what was written, as before.
  • Quit during an export. ffmpeg is now stopped and the partial file removed. Before, shutdownCleanup did not touch the export, so ffmpeg could keep running after the app closed.
  • Status line. It shows fps and time left, e.g. Rendering [NVIDIA NVENC]… 25% (300 / 1200 frames) · 112 fps · 1:05 left in English. The clock starts at the first frame.

Measured in the app

5 s of audio, isolated profile, run through --bench-export:

job frames video / audio notes
8 s fixed 240 8.000 / 8.000 s AAC; silence after 5 s (−inf dB); comment Scene: Kulüp
3 s, WAV 90 3.000 / 3.000 s AAC
3 s, MP3 90 3.000 / 3.005 s copied; packet boundary
8 bars @ 120 480 16.000 / 16.000 s comment BPM: 120
timeline (marker at 6 s) 180 6.000 / 6.000 s
empty timeline — refused "The timeline is empty, so it cannot set the duration."
cancel after 2.5 s — — no file, no .partial
quit after 3 s — — no file, no .partial, no ffmpeg process left

A 6 s PNG sequence over 5 s of audio wrote 180 frames into the final folder.

Verification

  • npm test: 3132/3132.
    • tests/export-job.test.js covers duration resolution, the pad/trim/copy rules, metadata, file names, the partial path, ETA, and the main, panel and MCP wiring.
    • tests/export-quit.test.js now checks the partial and promote path, and that quitting stops the export.
  • --smoke --smoke-export with an isolated profile: PASS, with no .partial left behind.
  • Panel over CDP:
    • Choosing "Sabit süre" shows the seconds slider (0:30), and choosing bars shows Bars and BPM.
    • The English labels and the status line translate.

CaYatur and others added 2 commits October 16, 2026 03:34
…data, no partial file at the final path (#523, #524, #528, #532)

Co-authored-by: caganturgut <271973834+caganturgut@users.noreply.github.com>
, #524, #528, #532)

Co-authored-by: caganturgut <271973834+caganturgut@users.noreply.github.com>
@CaYatur
CaYatur merged commit 55856cb into main Oct 16, 2026
5 checks passed
@CaYatur
CaYatur deleted the feat/export-job branch October 16, 2026 00:40
@cayadraft

cayadraft Bot commented Oct 16, 2026

Copy link
Copy Markdown

@CaYatur

CaYaDraft — pull request

Summary
Export: duration sources, audio length, scene/BPM metadata, clean cancel (#523, #524, #528, #532)

Files
CHANGELOG.md (modified, +13/-0)
@@ -36,6 +36,19 @@ GitHub. The full reasoning and the measurements behind each change are in [ROADM
31 s to 11 s, MilkDrop at 1080p60 from 31 s to 13 s, and MilkDrop at 4K from 60–67 s to 18–19 s.
The conversion matches ffmpeg's to within one level on luma; the scene itself is drawn exactly as
before.
+- Choose how long the export runs [523]. The length of the audio file (as before),…

README.md (modified, +5/-3)
@@ -17,7 +17,7 @@ layers and 40 GPU effects, an OBS overlay, Spout / Syphon, **project
Downloads
License: MIT
[![Platform](https://img.shields.io/badge/platform-Windows%20%…

README.tr.md (modified, +5/-3)
@@ -18,7 +18,7 @@ destesi**, ve MCP üzerinden yapay zekâ kontrolü.
İndirme
Lisans: MIT
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-111997.sv…

ROADMAP.md (modified, +31/-2)
@@ -93,7 +93,7 @@ hands, and a row only moves up once it ships.
|---|:--:|---|
| Per-app audio capture on macOS and Linux | v3.1.6 | On main (#514, #517). Linux verified in WSLg with PulseAudio; macOS written on ScreenCaptureKit and compiled in CI, never run on a Mac. Windows shipped in v3.1.3 |
| Live level meter per application | v3.1.6 | Done on main (#516): a moving dB-scale bar per ap…

src/admin/admin.js (modified, +62/-3)
@@ -3385,6 +3385,30 @@
type: 'select', path: 'export.format', label: 'Biçim', rebuild: true,
options: () => exportFormatOptions(),
},

  •      {
    
  •        type: 'select', path: 'export.duration.mode', label: 'Süre', rebuild: true,
    
  •        options: [
    
  •          { value: 'audio', label: 'Ses dosyasının süresi' },
    
  •          { value: 'seconds',…
    

src/exporter/exporter.js (modified, +6/-1)
@@ -423,7 +423,12 @@
if (prof) { prof.decodeMs = performance.now() - tp; tp = performance.now(); }
await setup(job);
if (prof) prof.setupMs = performance.now() - tp;

  • totalFrames = Math.max(1, Math.ceil(duration * fps));

Note
The local model is unavailable, so this is only the title and file list.


Stopping here. I will not merge, push, or change this pull request until you ask.

/caya explain describes the diff. /caya plan previews the next edit. /caya revise adds a commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Export: duration from several sources

1 participant