Skip to content
codegenic-devPublic

About

Simple 360 studio - video editor

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

insvedit

Fast, native editor for Insta360 .insv 360° video (developed against the X5), in Rust.

Run

cargo run --release -p insv-viewer -- sample.insv                        # real-time viewer + editor
cargo run --release -p insv-cli -- trim sample.insv -r 5-12 -r 20.5-26  # lossless .insv cuts → trimmed/
cargo run --release -p insv-cli -- reel sample.insv -r 4-12 --yaw 30     # 1080×1920 reel → reels/
cargo run --release -p insv-cli -- inspect sample.insv                   # metadata / calibration / IMU

Viewer controls: Space play/pause the clip · ⇧Space play/pause the reel · ←/→ step a frame · 1/2/3 perspective / 360° / tiny planet · H horizon off / level / lock · S stabilization off / low / medium / high / max · R export frame 9:16 / 16:9 · I / O mark segment in / out · Delete remove segment at playhead · ⌘Z / ⇧⌘Z undo / redo · drag look around · scroll zoom.

Stitching (toolbar) joins the two lenses. The camera's stored lens calibration is ~2–3° off for video, so every clip is first calibrated from its own footage (lens alignment fitted to the overlap ring, ~0.35 s at open). Then: Fast matches the lenses' brightness/colour and shows one lens instead of a ghost where they disagree; Dynamic also measures, per frame on the GPU, how far away things are around the seam and corrects the ~3 cm parallax between the lenses (brake lines, arms); Best (default) additionally cuts along the path where the aligned lenses differ least (dynamic programming per frame, steady over time), so close hands come out whole without ghosting or warping. All three export at the same speed (decode-bound); the analysis costs ~1–2 ms per frame on the GPU.

Filter (toolbar) picks one of 10 colour looks (Vivid, Warm, Cool, Teal & Orange, Golden Hour, Film, Moody, Dramatic, Vintage, Black & White) with a strength slider. It's graded in the view shader, so the preview matches the export exactly at no measurable cost; lossless .insv exports are never changed.

The edit (segments, transition, song, volumes, beat grid) is saved next to the file (<file>.insv.segments). Under the clip timeline, the reel timeline shows the segments back to back as the export joins them, with the music lane below. Play reel plays exactly what the export will look and sound like (cross-fades included); Play clip plays the whole source with its sound and the song following source time. Sound is the master clock for both.

  • ♪ Add music… (or drop an audio file on the window): mp3, m4a/aac, wav, aiff or flac, decoded and analysed in the background (≈0.2 s for a 3-minute song). It is normalized to −14 LUFS; the Music slider is relative to that, Original sets the camera's own sound (0% by default once a song is chosen).
  • Drag the song to choose which part plays; it snaps so a bar lands on the nearest cut. Drag the yellow marker to move the bar lines; fix the tempo with BPM (×2 / ÷2 for half/double-time, Re-detect).
  • Drag a boundary between segments to roll the cut (later cuts stay put); hold ⌥ to ripple (only the left segment changes, later cuts move). Boundaries snap to bars, then beats; hold ⌘ or turn off Snap to place freely. With a cross-fade, its middle is what snaps.

Export… (top right) exports the segments as lossless .insv files (Insta360 Studio-editable), one 9:16 reel per segment, or one merged reel with cut / crossfade / fade-through-black transitions, vertical 9:16 or wide 16:9 (the frame button / R). Videos are framed exactly like the outlined frame and can use 4× supersampling and Enhance (CAS sharpening + vibrance/contrast) at ~0.4 ms/frame; resolution up to 4K (2160×3840 / 3840×2160), H.264 or HEVC. Their sound is AAC-LC 256 kbit/s 48 kHz stereo: camera audio cross-faded / faded with the picture (10 ms fades at hard cuts), the song underneath (1.5 s fade-out at the end; per-segment reels get the stretch of song under their segment with 0.3 s fades), and a limiter at −1 dBFS.

CLI: insv reel sample.insv renders the editor's segments, transition and song; or override: insv reel sample.insv -r 4-8 -r 13-15 --merge --transition crossfade --transition-s 0.5 --music song.mp3 --music-start 0:42 --music-volume 100 --original-volume 0 [--no-music] [--quality standard|high|max] [--width 1080|1440|2160] [--wide] [--stitching fast|dynamic|best] [--filter teal-orange [--filter-strength 80]] [--codec hevc] [--no-supersample] [--no-enhance]

--snapshot out.png [--frame N] [--mode perspective|equirect|planet] [--horizon off|level|lock] [--smoothing off|low|medium|high|max] [--supersample] [--enhance] [--filter NAME] [--stitching fast|dynamic|best] [--size WxH] [--fov DEG] renders headlessly through the same GPU path and prints timings. For checking the UI without a screen, INSV_UI_SCREENSHOT=ui.png [INSV_UI_PLAY=clip|reel] [INSV_UI_AFTER_MS=3000] insv-viewer file.insv saves a screenshot of the window and quits.

Lossless trimming

Cuts start on the keyframe at or before the in-point (every 2 s on the X5) and end on any frame; frames are bit-identical to the source. The MP4 is rebuilt box for box like the camera writes it, and the inst trailer is rebuilt with IMU/exposure records trimmed to the camera's own margins and timing metadata (first/last frame clock, epoch, duration, frame count, trailer offset, file name) updated. Output is named like a camera recording (VID_<date>_<time>_00_<seq>.insv, clock moved to the cut start).

Performance (M3 Max, 2 × 3840² HEVC @ 29.97)

hardware decode, both lenses (pipelined) ~197 fps
frame → GPU (zero-copy IOSurface import) 0.12 ms
render 3840×1920 360° / 1080p view 0.34 / 0.09 ms
reel export 1080×1920 H.264 incl. mixed + encoded audio ~190 fps (6.3× realtime)
song decode + analysis (loudness, beats, waveform), 3 min mp3 ~0.3 s
lossless trim ~100 ms per segment

Layout

crate what
insv .insv parsing: MP4 sample tables + HEVC config, trailer records, metadata protobuf, lens calibration (Mei omnidirectional model), IMU, exposures; motion (gyro+accel orientation), trim (lossless cuts), mux (MP4 writer)
insv-decode VideoToolbox (macOS): pipelined hardware HEVC decoding of both lenses, H.264/HEVC encoding
insv-render wgpu stitcher/reprojector (view.wgsl), zero-copy IOSurface import, offscreen render + GPU NV12 conversion
insv-audio AudioToolbox (macOS): song + camera AAC decoding, loudness / beat-grid / waveform analysis, the mix (shared by playback and export), AAC encoding, real-time CoreAudio output
insv-export rendered exports (vertical reels): reel layout + transitions, decode → render → encode → mux with the mixed soundtrack; the project (sidecar) format
insv-viewer eframe/egui viewer and editor (segments, reel + music timeline, undo, export jobs)
insv-cli inspect, trim, reel, CPU reference stitch

Pipeline

mmap .insv → demux (both HEVC tracks) → VideoToolbox (HW, 3 frames in flight, 2 sessions)
  → NV12 IOSurface CVPixelBuffers → Metal textures aliasing the same memory (no copy)
  → fragment shader: view ray → IMU-levelled body frame → lens frame → Mei projection → YUV→RGB → seam blend
  → screen (viewer)  |  GPU RGB→NV12 → VideoToolbox H.264/HEVC → MP4 (export)
audio: camera AAC + song → mix (fades, volumes, limiter) → CoreAudio (playback clock) | AAC encode on its own thread → MP4

About

Simple 360 studio - video editor

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages