Skip to content

Import a video: File > Import Video…, drag and drop, and the agent's import command - #52

Merged
tszaks merged 3 commits into
mainfrom
feat/import-video
Oct 2, 2026
Merged

tszaks merged 3 commits into
mainfrom
feat/import-video

Conversation

@tszaks

@tszaks tszaks commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

What does this change?

You can now bring a video you already have into OpenScreen and edit it.

  • File > Import Video… (⌘I), and an Import Video… button next to Open Project… in the New Recording toolbar. The dialog offers MP4, MOV, M4V, WebM and MKV.
  • Drag and drop: drop a video anywhere on the window, on the New Recording screen or in the editor. While a file is over the window, an overlay says "Drop to import". In the editor, the usual "Save changes?" question comes first. Drags that aren't files (the timeline's clip reordering) are left alone.
  • Sound dropped on the editor (MP3, M4A, AAC, WAV, AIFF) goes on the music track at the playhead, through the same code as Add Music or Voiceover….
  • What an import does: it creates <file name>.openscreen in the recordings folder (Name 2, Name 3… if the name is taken). It copies the video in, and never moves or changes the original. Then it writes project.json (name, size and length from ffmpeg) and opens the editor.
    • A video the size of an iPhone or iPad screen (for example 1179×2556 or 1206×2622, from the phone's own Screen Recording) opens as an iPhone take: device frame, 9:16 canvas and tap detection.
    • Anything else opens as a screen video. It has no cursor track, so the Cursor tab and click/dwell zooms are hidden and off (recording.imported). Manual zooms still work.
  • Playback: I tested what Electron 41 actually plays by decoding a file of each kind. h264 and hevc (any bit depth or chroma), vp8, vp9 and av1 all play, in every accepted container. ProRes and mpeg4 play their sound over a blank picture, and ac3/alac play silently, with no error in either case. canPlayType can't detect this (it even says no to QuickTime, which plays). So the importer decides from a codec list:
    • a playable file is copied as it is;
    • a file with unplayable sound gets only its sound re-encoded to AAC;
    • anything else is converted to H.264 + AAC with the bundled ffmpeg.
      The progress sheet shows copy or conversion progress and has Cancel. On the same APFS disk the copy is an instant clone, so no sheet appears.
  • Errors: these each get a plain message, never a crash:
    • an unreadable or missing file;
    • a folder;
    • a file that isn't a video;
    • a file with no readable picture;
    • a full disk.
      The bundle is built in a hidden .import-<id> folder and renamed into place only when it is complete, so a failed or cancelled import leaves nothing behind. Quitting mid-import asks first.
  • Agent CLI: import <file> [--name N] does the same import and prints the bundle path and details as JSON. Progress goes to stderr.
  • Docs: AGENTS.md (command and caveat) and ARCHITECTURE.md (new "Importing a video" section).

The editor change is small and separate from the canvas code: a prop, one menu case, one drop listener, and an optional path on addMusic. Main now also refuses navigation, so a stray file drop can never replace the app with the file.

How was it tested?

  • npm run typecheck and tsc -p tsconfig.main.json pass
  • npm test passes (694 passed, 3 skipped). The new test/importVideo.test.ts covers: name de-duplication; sourceKind for phone, desktop and odd sizes; the transcode decision; drop routing (video → import, audio in the editor → music, other → ignored, mid-recording → ignored); the overlay label; error messages. It also runs real ffmpeg imports into a scratch folder: copy is byte-identical and the original is unchanged, de-dup, phone detection, ProRes → H.264/AAC, cancel leaves nothing, refusals leave nothing.
  • Tried in the app. I used a test instance with its own user data and recordings folder, driven over CDP, with the window hidden and ignoring the mouse. Drops were sent with Input.dispatchDragEvent and real file paths, so the path goes through webUtils.getPathForFile in the preload. No renderer errors in any run.
File Import Opens as In the editor Export (ffprobe)
1920×1080 h264 mp4 + AAC copied screen video, tabs Style/Zoom/Audio/Text plays 1920×1080, 6.0 s; a dropped .m4a joined the music track 1920×1080 h264 + AAC, 6.00 s
1206×2622 h264 mov + AAC copied iPhone take: Device tab, 9:16, frame plays 1206×2622, 6.0 s 1080×1920 h264 + AAC, 6.00 s, phone framed (contact sheet checked by eye)
1280×720 ProRes mov + PCM converted (full) screen video plays 1280×720, 4.0 s 1920×1080 h264 + AAC, 4.00 s
1280×720 vp9 webm, no audio copied screen video plays 1280×720, 4.0 s 1920×1080 h264, no audio, 4.00 s

Also checked:

  • A 40 s 1080p ProRes import showed the conversion sheet. During it, File > New/Open/Import were disabled. Cancel removed its staging folder and left the editor as it was.
  • Dropping a video on an editor with unsaved edits asked "Save changes to Product demo?" first.
  • A non-video drop showed no overlay and imported nothing.
  • On a small HFS+ disk image (no cloning), the streamed copy worked until the disk filled. Then the import failed with "There isn't enough free disk space…" and left no bundle.

Screenshots

New Recording toolbar, light and dark:

Drop overlay on the New Recording screen, light and dark:

In the editor: a video, and a sound (music track):

Conversion progress with Cancel, light and dark:

Imported iPhone screen recording, and an imported screen video (no Cursor tab):

In the screenshots the sidebar shows lighter under the dark overlay. This is because the test window's vibrancy isn't captured by CDP screenshots; the real window paints it.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@tszaks
tszaks merged commit 152cf79 into main Oct 2, 2026
1 check passed
@tszaks
tszaks deleted the feat/import-video branch October 2, 2026 03:07
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.

1 participant