Commit Graph

3 Commits

Author SHA1 Message Date
72f2754226 [0.1.8] Video capture phase 5: sound, from the computer and the microphone, in sync
- modules/Screen_Record/audio_source.jai: WASAPI, in loopback from the default output device
  (what the computer plays) and from the default input device (the microphone), asked for as
  48 kHz stereo float, which Windows converts any device to; a device that will not convert is
  taken as it is when it gives 48 kHz float. Packets carry the time they were heard. A device
  lost (unplugged, default changed) is opened again from the new default once a second.
- An audio thread mixes them onto the video's own timeline: the same time 0, less the same
  pauses (record_pause now keeps one account of time paused for both threads). A packet within
  30 ms of where its source left off follows on exactly; a source that sends nothing is silence,
  passed 200 ms late. Each 1024 samples every source has covered become an AAC frame.
- encoder.jai: an AAC stream (FFmpeg's aac, 160 kb/s) beside the video, written from the audio
  thread; both threads' packets meet in the file under a lock. The remux keeps it.
- [video] system_audio (true) and microphone (false). capture.json: Audio, AudioSources. A toast
  when a source asked for could not be opened.
- record-probe: -audio system|mic|both, the sound read back (length, level), and -sync-test,
  which flashes a white square and beeps together every 2 s, then finds both in the file.
- Measured: 20 s, beeps 0-21 ms from their flashes, no drift; both sources mixed, 5-18 ms;
  a 6 s pause cuts the same 6 s from sound and video; 3 min, 85 of 90 beeps within 3-24 ms and
  -14 ms from first to last, with 5 outliers (53-147 ms) where two beeps went missing. Tests:
  an MP4 with sound keeps its AAC stream through the remux into the library (30 checks).
2026-10-10 08:08:47 +01:00
93274a2b04 [0.1.5] Video capture phase 3: Ctrl+PrintScreen records a region into the library
- record_region, a new [global_hotkeys] action on Ctrl-PrintScreen (Windows only; none on
  macOS): starts a recording, or stops the one running.
- The overlay's video mode (screen_capture_win32.jai): red outline and magnifier; the drag held
  to the screen it began on; under 240 x 180 (record_size_allowed, in Screen_Record) the outline
  is dashed, the label gives the minimum, and letting go takes nothing; a click or Enter takes
  the whole screen; no pixels copied. With immediate, no overlay at all: the screen under the
  cursor, for PrintScreen while recording.
- src/app/screen_record.jai: records with modules/Screen_Record to %TEMP%/mcap at 30 fps; a
  recording that stops by itself keeps what it has, as does quitting (the shutdown step stops it).
  The MP4 goes into the library through the stills' jobs: a video .mcap in Screen Captures, the
  MP4 its original, a frame of it its rendered image, metadata.json as a still's, capture.json
  with Duration, FrameRate, VideoCodec, PosterTime, Encoder, Capture and DroppedFrames; the MP4 is
  deleted once it is in. The catalog reads a video's keys from capture.json too.
- The capture thread makes itself aware of each monitor's DPI: ImGui makes only the main thread
  aware, and Desktop Duplication refused the app's capture thread with DXGI_ERROR_UNSUPPORTED
  (the fallback recorded with Windows.Graphics.Capture, and the log said so).
- -record SECONDS records the screen under the cursor, puts it in the library and exits;
  -record-quit quits while recording instead. Both pass on a scratch library.
- Tests: a "screen recording" group (the size rule; an MP4 from the module's encoder written as a
  recording reads back, and the catalog takes it as a video). The segment overlay test no longer
  depends on the colours chosen in the app's own data folder.
- README, the format's README and the plan describe it.
2026-10-10 07:14:35 +01:00
9953ba6f1f [0.1.4] Video capture phase 2: Windows.Graphics.Capture, for when Desktop Duplication cannot run
- modules/Screen_Record/wgc_source.jai: the screen through Windows.Graphics.Capture, with
  hand-written bindings for its WinRT interfaces (capture item interop, item, free-threaded frame
  pool, frame, session 1-3, IDirect3DDxgiInterfaceAccess, IClosable). A small COM handler on
  FrameArrived sets an event per frame; when Windows refuses it the pool is polled each
  millisecond. The cursor is drawn by Windows; the yellow border is turned off where the system
  allows (Windows 11). A screen that changes size makes the pool again. WinRT's own calls are
  loaded from combase.dll at run time: runtimeobject.lib names no DLL for #library.
- capture_gpu.jai: what both sources share (the device on the screen's adapter, the region copy,
  the staging ring), so each is only "the next image's region into a texture".
- Record_Options.capture: AUTO (Desktop Duplication, else Windows.Graphics.Capture when it says
  fall_back), DXGI or WGC. Sources open on the capture thread, as WinRT objects belong to their
  apartment; record_start waits for it to say how that went. Record_Options.testing simulates the
  two-GPU failure, forces polling, or keeps the border, for record-probe.
- record-probe: -capture auto|dxgi|wgc, -simulate-unsupported, -poll, -border-test with
  -keep-border as its control, -cursor-test; DPI awareness set already is no longer reported as
  a failure.
- On the RTX 5080 laptop: auto falls back on the simulated failure; WGC records 4K at 60 fps with
  nothing dropped; its cursor and the one cursor.jai draws for duplication are the same; the
  border is off for an unpackaged app (0 yellow edge pixels, 14,214 with it kept);
  WDA_EXCLUDEFROMCAPTURE is respected; polling holds 30 fps. The plan records the results.
- README: Screen_Record's line, which held a carriage return in place of "\r" since 0.1.3.
2026-10-10 07:03:47 +01:00