Always on the latest: the download link tracks every notarized release. Existing installs auto-update from inside the app — no need to re-download.
Download latest
1.6.2 May 18, 2026 Per-Output Resolution + Preview Grid Reliability

Phasion Live 1.6.2

Per-output resolution + grid-preview reliability + a top-bar redesign. Each audience display now has its own publish resolution (720p / 1080p / 1440p / 4K / Custom), locked to the configured size. The "Preview: All" grid no longer leaks Output 1's stream as a backdrop behind the other tiles. And the top-bar mashup controls got cleaned up: thinner duration dropdown, a numeric mix readout, removed clutter (Speed / Auto / legacy global resolution dropdown), and a responsive layout that fits all your buttons inline at multi-col widths and reflows cleanly at narrow widths.

What's new

Per-output resolution

Each output now has its own publish + window size, settable independently from Settings → Output Windows. The Output 1 / 2 / 3 rows now show a resolution dropdown next to the display picker and the Windowed / Fullscreen toggle.

  • Quick presets: 720p, 1080p, 1440p, 4K, or Custom (any WIDTH×HEIGHT down to 320×180 — supports ultrawide, portrait, square, anything).
  • Window LOCKED to the configured size. Operators can no longer accidentally drag-resize an output window. The captured-via-Syphon frame matches the configured resolution 1:1 — no scaling, no aspect-ratio drift.
  • Each lane is independent. Output 1 can run at 720p (for a smaller projector), Output 2 at 1080p (main stage), Output 3 at 4K (LED wall) — all simultaneously. Each Syphon server (phasion1, phasion2, phasion3) publishes at its own lane's native resolution.
  • Overlays auto-scale. QR codes, scrolling text, captions, photo carousel, logos, applause emoji, trivia / poll cards — every overlay reads canvas.width for its sizing math, so each lane's overlays render at the right size for that lane's resolution. A 1080p output and a 720p output running the same scene look visually identical, just at different pixel densities.
  • Legacy "Output Resolution" global dropdown removed from Settings — the per-output dropdown inside each Output row is now the single source of truth. No more "did this affect Output 1 or all outputs?" ambiguity.

Why per-output matters

The 1.6.0 multi-output release shipped with Output 2 and Output 3 windows being freely draggable / resizable. That looked harmless, but SCKit window-capture scales the captured frame to the configured publish dims — so dragging Output 2 down to, say, 800×600 left Syphon publishing a 1280×720 stream that was an upscaled blur of the smaller window. The lock here makes the captured frame match the rendered frame exactly.

What's fixed

Preview: All — no more Output 1 bleed-through behind the grid tiles

When "Preview: All" was active, Output 1's single-tile capture stream stayed running in the background, visible as a backdrop behind the per-lane grid tiles. Operators were toggling Preview Active → Preview All to manually clear it. Root cause was an async race between applyVisibility() (which manages the single-tile preview) and _startGridImpl (which manages the grid). Three layers of fix: 1. applyVisibility now reads a gridActive flag and forces the single-tile stream off when grid mode is showing multiple lanes. 2. _startGrid and _stopGrid proactively trigger applyVisibility so the gate evaluates the instant grid state changes (instead of waiting for the next matchMedia / tour event). 3. The async startStream() re-checks gridActive after the getDisplayMedia await resolves and abandons the in-flight stream if grid mode flipped on mid-await — preventing a zombie capture from binding to the hidden mainVid element.

Mix slider — direction unified across every blending pattern

Patterns 3 (H-Split), 4 (V-Split), 6 (Radial), and 9 (Luma key) had their slider direction inverted relative to Crossfade and Noise wipe — at slider left, the user saw preset B instead of preset A. All five patterns now share the same direction:

  • Slider far LEFT → 100% preset A
  • Slider far RIGHT → 100% preset B
  • Slider centered → 50/50 split for the wipe patterns; centered transition threshold for the luma key.

Other fixes

  • Photos Syphon status text now reads "Syphon output disabled" instead of "Not running" — consistent with the AI Visuals panel.
  • Settings → Output Windows scroll now works in Settings popout windows (the multi-col overflow: hidden rule no longer leaks into Settings).
  • Column-width resize handle no longer drags adjacent columns when you adjust the column 2 / column 3 boundary at 3-col widths (CSS specificity fix on the @media (min-width: 1100px) grid template).
  • Preview height resize (⋯ drag) in "Preview: All" mode now scales the entire tile row proportionally instead of clipping the bottom of the tiles.

Top-bar polish

Compact, responsive mashup controls

The Visual Mix top-bar got a layout overhaul to use space more wisely at every width:

  • "Pattern" renamed to "Blending" — clearer semantic for what the dropdown controls.
  • Mix slider now has a numeric readout (e.g. 0.50) on the right edge so you can tell when it's centered without eyeballing.
  • Duration dropdown is now compact (~42px) — was hogging too much row width.
  • Speed slider + Auto-Mix button removed from the top bar — these are less-touched controls and were squeezing the Mix slider down to nothing at narrow widths. Auto-Mix is still available via the existing MIDI / OSC / phone-remote bindings.
  • Multi-col widths: all 13 items (Rand A · Gen A · style · ⇄ · style · Gen B · Rand B · A+B · 🔒 · Change · Same · Fade · 3s) stay inline on a single row — no more wrapping at moderate window widths.
  • Single-column widths: cleaner two-row layout —
  • Row 1: per-lane preset controls (Rand A · Gen A · style · ⇄ · style · Gen B · Rand B · A+B)
  • Row 2: master macros (Change · Same · Fade · 3s) sit just above the Visual Effects section, evenly distributed across the row
  • Lock button auto-hides on the wrapped master row to keep it focused on the 4 macro controls; still accessible at wider widths.

Visual Effects / Setlist / Demo header alignment

  • All three collapsed headers (FX, Setlist, Demo) now render at exactly the same height (~25px) with text vertically centered — was previously a few pixels off, with text looking top-aligned because of residual padding-bottom on the collapsed .section-body.
  • Tightened the gap above the first primary group below the FX/Setlist stack (was 14px, now 4px) so the stack reads as a unified bank.

Hidden Syphon Position Adjust panel

The "📐 Syphon Position Adjust" sub-section in Settings → Output Windows is now hidden by default — the per-lane SCKit crop math has been stable for several releases and the manual offset sliders weren't being touched. Inputs stay in the DOM as stubs so existing handlers don't error; the section can be re-enabled by removing one style="display:none" wrapper if a future SCKit regression makes manual adjust necessary again.

Upgrading

Existing 1.6.x users pick this up automatically on the next "Check for updates". After installing, restart Phasion Live. Your existing single global resolution is preserved as Output 1's default; Outputs 2 / 3 inherit the same dims initially but can now be changed independently via Settings → Output Windows.

Behind the scenes

  • New config.laneResolutions = { "1": {w,h}, "2": {w,h}, "3": {w,h} } storage. Falls back to the legacy global outputWidth/Height for installs without per-lane entries, so existing setups continue to work without re-configuring.
  • New set-lane-resolution(lane, w, h) IPC: resize window → push new resolution to renderer → restart SCKit capture at new dims. Lane 1 also routes through here for consistency, while the legacy set-viz-size IPC keeps working as a shortcut.
  • Each lane window's did-finish-load re-pins setContentSize(w, h + 28) defensively so the captured frame is exactly the configured dims from the first publish (matches how Lane 1 already did it).
  • useContentSize: true + resizable: false on lane construction — both belt-and-suspenders against accidental drift.
  • Master-row layout uses CSS flex-wrap: nowrap at multi-col widths (≥740px) + JS re-parenting at narrow widths (<740px) so the master gang lives in different DOM positions for the two layouts without duplicating any elements.
1.6.1 May 17, 2026 Syphon multi-output hotfix

Phasion Live 1.6.1

Hotfix. Lane 1's Syphon server (phasion1) was publishing Lane 3's content in some multi-output sessions. This release fixes the routing.

What's fixed

Multi-output Syphon routing — phasion1 no longer shows phasion3's content

In 1.6.0, the SCKit window-capture used to feed Lane 1's Syphon server (phasion1) matched windows by substring — searching for any OS window whose title contained "Phasion Live — Output". Lane 2 and Lane 3 use titles "Phasion Live — Output 2" and "Phasion Live — Output 3" — both of which contain that substring.

Depending on the order SCShareableContent returned windows on a given boot, Lane 1's capture could lock onto Lane 3's window instead of Lane 1's. Result: downstream apps (Resolume, Synesthesia, OBS) saw phasion1 publishing whatever Lane 3 was showing — and phasion3 showed the same thing because it correctly bound to Lane 3.

The lane 2/3 path already used exact-match (isEqualToString:) for window lookup; only Lane 1 was using the loose substring match. This release equalizes the matching logic so every lane's Syphon server is guaranteed to publish its own lane's content.

Why this manifested only in the packaged build but not in npm start: pure SCKit window-enumeration ordering luck. The bug was latent in both — in dev, lane 1's window happened to be returned first; in the packaged build, lane 3's was. Same code path, different order.

Upgrading

Existing 1.6.0 users pick this up automatically on the next "Check for updates". After installing, restart Phasion Live and test with Resolume / Synesthesia: each of phasion1, phasion2, phasion3 should now publish its own lane's content.

1.6.0 May 17, 2026 Multi-Output

Phasion Live 1.6.0

Multi-output. One Phasion install can now drive up to three independent audience displays — different scenes, different presets, different feeds — from a single controls window. This is the biggest update since Phasion Live shipped.

What's new

Multi-output engine

  • Up to three independent outputs running in parallel. Each lane is its own visualizer window with its own preset slots, its own scene, its own audio-reactive render loop.
  • Output tab strip at the top of the controls window — click a tab to focus that lane; every per-lane slider, preset, and feed source below the strip retargets to it automatically.
  • Per-lane preview tiles so you can see all three outputs at a glance. Preview: Active (single tile follows the focused lane) and Preview: All (grid of every open lane at 15 fps to save CPU).
  • Per-lane Syphon + ScreenCaptureKit publishing so each output is a separate routable signal for Resolume, Synesthesia, OBS, Mad Mapper, etc.
  • Multi-output macros — three buttons appear in the top bar when 2+ outputs are open:
  • 🔁 Change All — randomize A+B on every output
  • 🎯 Same on All — load the SAME random A+B pair across every output
  • 🌀 Smooth Fade — coordinated fade-to-black transition across every output
  • 🎲 A+B button — randomize both presets on the active output in one click.
  • Per-lane preset mode toggle (Settings → Performance) — flip a lane between Blend A+B (default) and Single Preset. Single-preset mode skips the mashup pass for CPU savings on lanes that don't need variety (e.g. a sponsor-loop background lane).
  • Per-lane mix / pattern / speed memory — top-bar sliders snap to each lane's saved values when you switch tabs.
  • Setlist cue model — each setlist entry is a snapshot of every lane's preset, scene, and feed source. One click recalls a full multi-output state.
  • Scene-target chip row — multi-select which outputs a scene activation lands on. Routes carousel, AI, scrolltext, captions, trivia, crowd play, etc. on a per-lane basis.

License tiers rewritten around output count

  • Home ($60/yr) — 1 audience output. Visual engine + AI Visuals + lyrics.
  • Pro ($19/mo or $190/yr) — 2 audience outputs + full audience-engagement suite (QR, Crowd Play, Poll, Trivia, Applause, Photo Carousel, Scrolling Text, Branding Overlays, Setlist, Demo Mode, Moderation, Scenes, Remote Control, MIDI/OSC).
  • Trial — all features including 3 outputs, watermarked, for evaluation.
  • Venue — same as Pro plus 3 audience outputs, custom branding, white-label domain options. Designed for permanent installs at clubs, breweries, restaurants.

MIDI + OSC bindable across all multi-output controls

  • Lane focus: setActiveLane1/2/3, laneNext, lanePrev (MIDI notes or CCs) and /lane/active <n>, /lane/next, /lane/prev (OSC).
  • Multi-output macros: mashupChangeAll, mashupSameAll, smoothFadeAll, mashupRandomBothActive (MIDI) and /mashup/all/{change,same,fade}, /mashup/random/ab/active (OSC).
  • Color theme + room controls: theme cycle next/prev/off + strength, room brightness + contrast + cap on/off + cap level — all bindable on both surfaces.
  • TouchOSC outbound — Phasion emits /lane/active/state <n> on every focus change so TouchOSC layouts can light up an "active output" LED.

Phone remote — multi-output awareness

The phone-served remote control page (http://<lan-ip>:3131/) now shows:

  • Output 1 / 2 / 3 tab strip at the top, mirroring the desktop. Tapping a tab focuses that lane; every per-lane command below targets it.
  • 🔁 Change All / 🎯 Same All / 🌀 Fade All buttons inside the Visual Mix card. Both controls auto-hide in single-output mode.
  • The desktop tab strip + remote tab strip stay in sync over SSE — switch focus on either surface and the other catches up within ~100ms.

Visual Effects strip — redesign

  • Slim collapsed header (~24px tall) — collapsed by default so the strip doesn't crowd the layout. Click ▸ ⚡ VISUAL EFFECTS to expand. Saves ~86px of vertical space for operators who drive FX via keyboard / MIDI.
  • Single popout button row at multi-col widths — right-aligned next to the strip, no double-rendering.
  • Cleaner strobe/black-out button labels at narrow widths.

Branding Overlays — match scene color

  • New per-image 🎨 Match scene color checkbox + tint-strength slider in both the Branding Overlays panel and the Scene Editor logo overlays.
  • Each lane samples its own butterchurn canvas every ~1.2s and applies a CSS-filter chain — drop-shadow glow + depth + hue-rotate + saturate — so logos glow with the preset's dominant color.
  • Per-frame shortest-arc hue smoothing so transitions glide rather than snap.
  • Scene editor adds bulk "Match scene color (every logo) — All on / All off" buttons.

Guided tour — tier-aware

The onboarding tour now reads body[data-license-tier] and filters its 26 steps to match what the operator can actually do:

  • Home tier sees 11 steps (visual engine + AI Visuals + lyrics).
  • Pro / Trial / Venue see all 26 including Multi-Output Tabs, Change All / Same on All, Audience QR + Crowd Play + Poll + Trivia + Applause, Scrolling Text + Photo Carousel, Branding Overlays, Setlist, Demo Mode, Scenes, Remote Control.
  • Welcome step is tier-specific (🏠 + "three minutes" for Home vs ⚡ + "six minutes" for Pro).

Other workflow wins

  • Emoji applause — each reaction now fires on one random open lane (or chip-mask subset) instead of fanning to every output. Operator bursts use round-robin sweep; audience taps use pure random.
  • Top-bar follows the active lane — change tabs and the mashup sliders, preset names, and scene buttons all retarget without an extra click.
  • Lane open/close lifecycle — restoring saved lanes on app launch now triggers a full UI repaint (preview grid, setlist slots, tab strip) so a 3-lane setup looks correct from the first frame.
  • AI Generate styles — preset generation now picks from style buckets (Cyberpunk, Nature, Cosmic, Geometric, Abstract, Glitch) instead of one global pool, retries on failure, and exposes per-slot dropdowns.

Fixes (since 1.5.4)

A non-exhaustive list of bugs squashed across this release:

  • Preview tile cross-renderer race — the per-tile getDisplayMedia FIFO queue is now per-webContents-id, eliminating "Output 1 shows controls window / desktop" misroutes when the single-tile preview and grid build raced on boot.
  • Settings popout missed lanes opened from Main window — Settings reads vizWindows from main rather than its own stale module state.
  • Single-preset mode state desync — Settings popout's checkbox now broadcasts to Main via IPC so the top bar's B-slot chrome flips on every window in lockstep.
  • First setlist cue click after reload activated only lane 1 — boot lane recovery now exposes a promise that _activateCue awaits before committing its lane filter, eliminating the race.
  • Scene transitions on multi-output — per-lane _pendingFTBConfigByLane Map + lane-tagged midpoint IPC routes each lane's pending config to the correct apply path. Multi-output bursts now honor the configured transition style (random / wipe / dissolve / zoom / glitch) on every lane.
  • Open Mic / scene-swap overlay peek-through_wcClearTestSubmissions no longer fires an unconditional _wcMenuPushLive, fixing the rare flash of Open Mic overlay during a scene-to-scene transition right after activity exit.
  • Stale feed globals during multi-lane burstsactivateFeed() now captures the LANE's previous feed up front and gates its teardown IPCs on that, so a lane-2 burst clearing the global flag doesn't strand a carousel running on lane 1.
  • Preview popout close → grid order wrong — the "Preview: All" grid now auto-rebuilds when the popout closes so tiles return to correct lane order without the operator manually toggling modes.
  • Column-width resize broken at 3-col widths — a CSS specificity collision between the @media (min-width: 740px) and @media (min-width: 1100px) rules caused the 2-col template to win at 3-col widths, sticking col 3 on an auto-generated implicit track. Specificity equalized.
  • Settings window scroll — multi-col layout's overflow: hidden was leaking into Settings windows, clipping the tail of long sections (Branding, Privacy). Settings now correctly scrolls.
  • Trial/auto-play deactivation + lane recovery on controls reload — controls reload re-syncs from main rather than starting from a stale snapshot.

Under the hood

  • New native multi-output substrate: each lane gets its own BrowserWindow, its own SyphonMetalServer slot, and its own SCKit capture pipeline. Server names are phasion1, phasion2, phasion3 so downstream apps (Resolume, etc.) can address them individually.
  • New IPC namespace for lane lifecycle: open-output-lane, close-output-lane, list-open-lanes, output-lane-opened, output-lane-closed.
  • New IPC + handlers for phone-remote multi-output sync: remote-state-active-lane, remote-state-recompute-lanes. Lane focus on the desktop pushes via pushSSE so every connected phone repaints its tab strip within ~100ms.
  • shared.toVizLanes is now a lane-aware fan-out: messages with lane: N route to that lane only; messages without lane fan to every open lane.

Upgrading

Existing 1.5.x users pick this up automatically on the next "Check for updates" via the in-app updater. After installing, restart Phasion Live to load the multi-output substrate.

A note on the engine

The audio-reactive engine itself is still butterchurn. Multi-output runs three independent butterchurn pipelines side by side — each consuming the same audio analyzer, each producing a fully independent render. No shared GPU state between lanes, no preset cross-talk. Your existing presets, custom themes, scenes, setlists, and branding overlays all work without change — they're now just multi-output-aware.

1.5.6 May 13, 2026 Fix trial-expired pricing link

Phasion Live 1.5.6

Patch release — fixes a broken pricing link in the trial-expired modal.

What's fixed

Trial-expired pricing link

When the 10-minute free-trial timer fires in v1.5.5, the modal's "See pricing →" button pointed at phasion-live.pages.dev/pricing.html — a Cloudflare Pages project that was retired shortly after 1.5.5 shipped. Result: trial users clicking through to upgrade hit a 404 instead of the pricing page.

This release re-targets that button at the live marketing site (phasion-live.corunography.workers.dev/pricing.html).

No other behavior changes — same 10-minute trial, same modal, same Quit button, same all-other features as 1.5.5.

Upgrading

Existing v1.5.5 users will pick this up automatically on the next "Check for updates" via the in-app updater.

1.5.5 May 13, 2026 10-min free trial + new pricing flow

Phasion Live 1.5.5

10-minute free-trial timeout and a refreshed pricing flow.

What's new

Free trial now caps each session at 10 minutes

Unlicensed sessions run for 10 minutes from app launch, then freeze. This matches the in-browser trial at https://phasion-live.corunography.workers.dev and gives prospects a clear "you've seen what it does, here's the upgrade" moment instead of a permanently watermarked free product.

  • Wall-clock 10-minute timer armed at launch. Only fires when license state resolves to unlicensed or signin_needed — licensed/grace sessions never see it.
  • Mid-session license activation cancels the timer. Sign in and activate during the window and the session continues uninterrupted.
  • Freeze semantics — when the timer fires, the visualizer's render loop cancels (the last frame stays on-screen, watermark on top), audio capture stops cleanly, and the AudioContext is suspended.
  • Trial-expired modal in the controls window. Undismissable except via:
  • See pricing → opens https://phasion-live.corunography.workers.dev/pricing.html in the system browser.
  • Quit Phasion Live exits the app.
  • Reset on relaunch — quit and reopen for a fresh 10 minutes. No persistent lockout.

Marketing site (corunography.workers.dev)

  • New /pricing.html — Free / Web ($30/yr) / Home ($60/yr) / Pro ($19/mo, $190/yr annual) / Venue tiers, with a Monthly ↔ Annual toggle on Pro.
  • /try/ browser-based trial with the same 10-minute cap as the native app, dual-preset blending, audience-display popout, 1,144 base presets + 14k bonus presets loaded from R2 storage.
  • Keyboard shortcuts in /try/A/B/S for slot randomize + swap, arrow keys for blend + sensitivity, F for fullscreen, ? for the help panel.

Under the hood

  • New IPC channel app:quit so the controls renderer can request a clean shutdown.
  • to-viz channel gets a new message type trial-expired which cancels the rAF chain in visualizer.js and tears down audio capture.
  • Bonus preset library (54 MB) now lives in Cloudflare R2; web /try/ fetches it cross-origin and caches in IndexedDB for return visits.
1.5.4 May 11, 2026 AI Generate styles + boot stability + song-title fix

Highlights

🎨 AI Generate gets curated style buckets

Pick a mood per slot via a tiny inline dropdown next to each ⚡ Gen button: 🧊 Calm · ⚡ Aggressive · 🌀 Psychedelic · 📐 Geometric · 💧 Liquid · 💥 Strobe · 🎭 Hybrid · 🎲 Random. Mashup any two moods (Calm × Strobe!) by setting different styles per slot. Default 🎲 Random rolls a fresh mood each click so generations look distinctly different, not slight variants of each other.

🎭 Hybrid mode — cross-pollinate two real presets

Pulls frame_eqs from one preset and pixel_eqs from another. Real butterchurn JS recombined — always compiles, never the same chimera twice.

✨ AI Generate retry on failure

Now retries up to 3 times if a generated preset fails to compile, and stops the spinner immediately on total failure instead of waiting for the 30s safety fallback. Previously about 20% of clicks would silently no-op.

🎬 Song-title overlay no longer freezes the visual

The backdrop-filter compositor layer is now pre-warmed at parse time (same pattern as the QR overlay). The GPU doesn't rebuild it on each Shazam match — no more visible hitch when a song appears on screen.

🖥 Media-capture boot stability

Defensive stop+drain in startMediaCapture, proper Phase 4 ordering after the boot preset apply, and a guard against double-mediaStart. Eliminates the intermittent SIGSEGV on launch when a preset's auto-restart raced with the async restore IIFE.

🎵 Beat-sync + Photo-counter are now true global preferences

Activating scenes that previously baked beatSyncEnabled:false no longer flips your global toggle off. Live BPM also visible in the header next to FPS while Beat Sync is active. Photo-carousel counter follows the same pattern.

🧹 Duplicate scenes cleaned up

One-time dedupe-by-name on launch keeps your customised originals.

🧰 Small UX polish

  • Window-picker buttons (Refresh / Restart) no longer get clipped in the Media Capture section at narrow widths.
  • Pack editor in Stage Management now separates prompts with blank lines so long prompts don't blur together.

---

Direct download (always latest): Phasion-Live.dmg

1.5.3 May 10, 2026 AI Visuals prompt packs + cross-display media-crop fix

Highlights

🤖 AI Visuals prompt packs

A new PACK dropdown above the category selector in the AI Visuals section. Pick a themed pack to override Roll and Auto-cycle — they'll now draw from the pack's prompts instead of the category engine. Ships with a built-in 🤖 AI Visuals pack of 20 starter prompts (psychedelic / cosmic / surrealist / artist-style), and the Pack creator in Stage Management → Prompt Packs gains a 🤖 AI Visuals option so you can author themed packs for specific events.

🎬 Media-crop startup race — fixed

Crops applied from a saved preset now snap in immediately on launch — no slider nudge required. The root cause was window.devicePixelRatio briefly returning 1 before Electron settled the Controls window on its display, then becoming 2. That meant the first sendCropUpdate after launch shipped half-scaled crop values, and any later nudge shipped double-scaled. Hardcoded the scale so it can't race.

🖥 Cross-display preset switching

Switching a saved preset across monitors mid-session no longer requires a manual Restart Capture. applyMediaCropPreset now auto-cycles the SCKit stream (500ms settle) so the bitmap context re-binds to the new display's frame dimensions. Per-monitor presets stay valid since each one's stored slider values are still calibrated to that monitor's source frame.

✏️ Prompt-pack editor readability

Prompts in the pack editor textarea now have a blank-line separator between them so long prompts no longer blur into a wall of text. Larger font, more line-height, refreshed helper copy.

---

Direct download (always latest): Phasion-Live.dmg

1.5.2 May 10, 2026 Copy-link buttons + audio source auto-switch + persistence fix

What's new

  • 📋 Copy-link buttons next to the URL chips in Audience QR and Remote Control sections. Click the chip to open in browser; click the button to just copy the link. Shows ✓ + "Link copied!" toast confirmation. Uses Electron's main-process clipboard via IPC so it works regardless of focus state.
  • Audio source auto-switch — changing the audio device dropdown now re-fires start-audio immediately when previously connected. Before: dropdown change reset the badge but the old device kept streaming until you clicked Connect again. Fixed.
  • Enable-state persistence fixpreload.setMediaEnabledSync now actually uses ipcRenderer.sendSync. Previously it was async-aliased, so the renderer's quit-time write didn't complete before main flushed state to disk. The "I enabled it but it forgot after restart" bug is fixed.

Media Capture

  • ⟳ Restart button added next to the window picker in Media Capture settings. One click does a clean stop + 500ms settle + start, forcing SCKit to re-bind to the source window's current dimensions. Use it after a monitor switch, source resize, or preset reload if the cropped image doesn't match.

Known limitation

On launch, the crop sometimes doesn't visually apply until you nudge a crop slider by 1 pixel. The ⟳ Restart button is a one-click workaround. We have an open investigation into this — the root cause is in the native syphon addon's binding behavior that we don't have source access to. Tracking for a future release.

Install

Apple-Silicon Macs only. Direct DMG download. Signed and notarized.

1.5.1 May 10, 2026 Media source: Syphon ↔ display alignment + audio auto-switch

Headline fix

Same crop slider values now produce identical framing in both the Phasion Output window AND any Syphon receiver (Synesthesia, Resolume, OBS Syphon, etc.). The on-screen display canvas had a hardcoded "+21 src px top, +23 src px bottom" compensation baked into its render loop; it's been removed. Calibration is once-and-done.

Media source improvements

  • DPR-aware crop scaling. Native SCKit captures at physical pixels on Retina displays — without DPR scaling, the same crop value cropped half as much. Fixed.
  • Aspect-matched output. Output width now derives from the cropped-source aspect ratio instead of a hardcoded 16:9 table, so SCKit's resize step doesn't stretch the cropped frame.
  • Live window-bounds sync. As you drag/resize the source app's window manually, Phasion's X/Y/W/H sliders now follow along (1.5s poll). Saving a preset captures the truth, not stale values from when capture was first configured.
  • Apply-preset ordering. Window resize fires first and awaits the AppleScript completion (plus 150 ms settling) before the crop applies. Eliminates the "black bar at top" from crop landing against stale capture dimensions.

Audio source

  • Auto-switch on dropdown change. Picking a different audio source now re-fires start-audio immediately — before, the badge changed to "disconnected" but the previous device kept streaming until you clicked Connect again.

UI polish

  • Send Fullscreen button is now centered in the Output Preview header bar.

Install

Apple-Silicon Macs only. Direct DMG download. Signed and notarized.

1.5.0 May 9, 2026 Multi-tier licensing + captions polish

Highlights

  • Multi-tier licensing. Engine, Trial, Pro, and Venue tiers now gate features per a single tier-rank table.
  • Trial (signed-out or no license) — full Pro feature access with watermark.
  • Engine — visual core + AI Visuals + Lyrics & Captions only. Audience features locked. Auto-lands on a stripped-down default scene that just shows the title pill + lyrics overlay.
  • Pro — everything except Whitelabel Branding.
  • Venue — everything, including Whitelabel Branding.
  • Click any greyed-out feature to open a styled in-app upgrade modal that links to the pricing page.
  • Hide locked features toggle (Settings → License) collapses inaccessible sections out of the layout. Engine + hide-locked drops to a clean 2-column workspace.

Captions / Shazam fixes

  • Title now paints for songs LRCLIB has no synced lyrics for — instrumentals and rare tracks show the title pill instead of nothing.
  • Toggle off → toggle on while same song plays restores the overlay immediately. Re-enable on a new song no longer gets short-circuited by stale state.
  • Opening Settings no longer kills the on-screen title/lyrics. Fixed a long-standing race where a secondary window's renderCaptionModels call fired lyrics-disable to the shared visualizer.
  • Cached title/lyrics repaint automatically when scene visibility flags flip from suppressed → visible — Shazam recognitions caught during a scene transition aren't lost.

Other

  • Sign-in dialog: removed the in-app "Create account" tab. Accounts are created via the Lemon Squeezy checkout.
  • Output Preview: Send Fullscreen button now centered in its header bar.
  • New default scene: default-engine — minimal preset designed for the Engine tier.

Install

Apple-Silicon Macs only. Download the DMG, drag to Applications. Signed and notarized.

1.4.28 May 8, 2026

v1.4.28

Bug fixes:

  • Fixed demo photos not appearing on audience phones (QR voting page) — photos were missing the image data needed for remote devices
  • Fixed demo assets not included in packaged builds (v1.4.27)
1.4.27 May 8, 2026

v1.4.27

Bug fix:

  • Fixed demo photos (Caption from Crowd, Photo Contest, Pet Photos) not appearing in installed/packaged builds
1.4.26 May 6, 2026

Electron 41, 2-col responsive layout, Metal Syphon preview, photo pipeline overhaul, friendly link labels, clean-shelf launches

1.4.25 May 5, 2026 Clean-shelf launches

Three UX fixes that landed after a stream-of-consciousness pass through the controls window.

Fixes

  • Clean-shelf launches. Every launch now opens with all sections, menu groups, settings categories, and moderation subsections collapsed. The single exception: Output Preview still remembers its last state across launches. Mid-session expand/collapse still works exactly as before — it just doesn't carry over to the next launch. The "open the app, see the room running, expand only what I need" pattern, made literal.
  • Light-mode FX buttons fixed. The visual effect buttons (SHAKE, ZOOM, CRUSH, BLUR, SPIN, HUE, SQUEEZE, RIPPLE, KALEID, PIXEL, WAVE, GLITCH) had multi-col rules slammed to pure black with !important, making them slab against the pale page chrome in light mode. Light-mode overrides now win the cascade with white fill, neutral grey text, and a soft red active-state for the ISF toggle buttons.
  • BLACK strobe button no longer dominates. In light mode it now sits in a mid-grey gradient (#8a8a90 → #6a6a70) — readable as "the dark one" without slabbing pure black against the rest of the row. Press / strobe-flash still goes to true black for the active feedback moment.

Cleanup

The new build also strips legacy persisted collapse-state keys from venue.json on first launch (collapsedSections, collapsedMenuGroups, collapsedModSections, etc.). They're all unused now.

1.4.24 May 5, 2026 Smoother launch (CLS 0.66 → 0.00)

Big perf win on the controls-window launch path.

What changed

A DevTools performance trace caught the controls window racking up ~30 layout shifts and a 0.66 Cumulative Layout Shift score during the first ~1.4 s of every launch. Cause: the section / menu-group / mod-section initializers each apply the .collapsed class to many elements at once, triggering all their max-height / margin-top / opacity transitions to fire simultaneously on a 9k-element DOM.

The fix:

  • <body> boots with a .no-transitions class that disables every transition + animation on every descendant.
  • After the startup IIFE finishes, the class is removed in a double-rAF — so all initial state is applied without animating, then transitions resume normally for any subsequent operator interaction.
  • Two scroll-indicator polls (the controls-window indicator and per-column overflow detectors) early-return while .no-transitions is active, so their forced layouts don't compete with the init burst.

Results

  • CLS: 0.66 → 0.00
  • Visual experience: black → settled state, no chaotic animation in between.
  • CPU usage during init drops noticeably (per operator testing).
  • Forced reflows during init: cleared.

LCP is bounded by the dev/Webpack bundle parse + synchronous init code; further wins would require code splitting, deferred for now.

1.4.23 May 5, 2026 Setlist heal, render race, white-label demo fallback

Three fixes that emerged from v1.4.21–22 testing.

Fixes

  • Damaged setlists self-heal on load. v1.4.21's bad scene-ID remap rewrote some setlists' working timestamped sceneIds to default-* IDs that had been tombstoned, leaving every entry as "⚠ Deleted." loadSetlists() now resolves each entry against the current scene library and, when the ref is broken but a known timestamped fallback exists, swaps it back. Working refs are never touched. Existing Ambient Setlists come back to life automatically.
  • No more "Deleted" flash on startup. Scene and setlist loads were sibling promises racing; whichever resolved first rendered with stale data. After scenes finish loading, the setlist UI now re-renders so names settle in place without waiting for the next user action.
  • White-label demo logo fallback. When an operator enables Venue Branding without uploading a custom logo, the audience page now serves the bundled OnlyJams demo logo instead of letting the Phasion Live default header leak through. The settings UI shows the demo preview with an italic "Showing demo logo — upload your own to replace it" note; the Remove-logo button hides when only the demo is active (so it doesn't read as broken). Removing an uploaded logo tells the operator the audience now sees the demo until they upload a replacement.
1.4.22 May 5, 2026 Setlist scene-ref repair (safe), pill text contrast

Two corrections building on v1.4.21.

Fixes

  • Ambient Setlist entries no longer show as Deleted. v1.4.21's scene-ID remap was the wrong call — it would have rewritten setlist entries from working timestamped IDs to default-* IDs that some operators have tombstoned. The remap is removed; the seed setlist keeps its original timestamped IDs. In its place, loadScenes() now backfills any missing scenes from seed/scenes.json on every launch (same merge pattern as the built-in defaults, with tombstones still respected). Upgrade installs whose scenes.json predates the timestamped seed scenes get them re-merged automatically. The "Ambient AutoPlay" → "Ambient Setlist" rename from v1.4.21 stays.
  • Output-display pill text + × are now black. White on amber was hard to read at 10px font size; black against the warning amber reads cleanly. Bumped font weight to 700 and adjusted hover states to dark translucent overlays so contrast holds.
1.4.21 May 5, 2026 Default marquee, setlist repair, preview-first columns

Three rough-edge fixes for fresh installs and upgrades.

Fixes

  • Default marquee position 100 (was 97). Earlier default left a small gap at the bottom of the canvas under the new linear semantics. Migration bumps any leftover 96/97 to 100 on next launch; anything you set explicitly is preserved.
  • Setlist scene refs repaired. The shipped seed setlist referenced scenes by timestamped IDs that only existed in the seed bundle, while existing installs only had the canonical default- IDs from defaultScenes.js. Result: 10 of 11 setlist entries showed as "⚠ Deleted" on most upgrade installs. Two-pronged fix: the seed setlist now uses default- IDs, and loadSetlists() runs a one-time remap so any in-the-wild setlist with old timestamped refs gets repaired on next launch. Also renames the seeded "Ambient AutoPlay" → "Ambient Setlist".
  • Preview-first column defaults. On first launch (and any install where you haven't dragged the column resize handles yet), the controls window now opens with the left and right columns collapsed to their min width and the center column — which holds Output Preview — taking the lion's share of available width. Drag the handles to rebalance; your saved widths win on subsequent launches.
1.4.20 May 5, 2026 Single-monitor friendliness

Quick follow-up to v1.4.19 fixing four friction points around output-display setup.

Fixes

  • Display picker hint redesigned. The big "Pick your output display" overlay that covered the inline preview on first launch is gone. Replaced with a small dismissible amber pill in the title bar — click the text to open Output settings, click the × to dismiss. Stays gone across restarts.
  • Pill auto-hides during the guided tour and comes back when the tour ends, so the tour's spotlight isn't competing with a permanent banner.
  • ESC now exits fullscreen display mode. Recover from an accidental Send Fullscreen on a single-monitor setup. Gated on display-mode so it doesn't hijack ESC during normal windowed use.
  • Display selection now actually persists across restarts. Fixed a race between main-process and renderer config writes that was wiping the saved display ID immediately after every Send Fullscreen — which is also why Send Fullscreen sometimes used the wrong display.

Recommended

If you're testing on a single-monitor machine, this build is for you. Multi-monitor users will find Send Fullscreen reliably remembers the right display now.

1.4.19 May 4, 2026 Electron 41 + smoother photo demos

Highlights

Electron 41

Upgraded from 35 → 41. Includes Chromium 140 and the security/perf improvements that came with it. All native modules rebuilt for the new ABI.

Photo demos no longer freeze the inline preview

Three layers of fix for the Caption-from-Crowd stutter:

  • Demo photos skip the base64 round-trip entirely — the on-disk asset path is plumbed straight to the renderer.
  • Real photos decode the base64 once up front, then share the file path with the NSFW classifier, OCR, and history-save (was three redundant 3MB Buffer decodes).
  • NSFW inference moved into a sibling utilityProcess so the ~150–300ms ONNX work runs in a separate V8 isolate. Includes a fail-safe: if the classifier errors for any reason, the photo gets flagged for manual review rather than silently passing through.

Syphon polish

  • Native Metal preview window (zero-copy GPU path).
  • On-demand JPEG tap drives the controls-window inline preview at ~15fps when Syphon output is enabled.
  • Rounded-corner regression fixed (Electron 38+ had been masking the window content layer, leaking through to SCKit/Syphon as transparent corners). Syphon publishes a clean rectangular canvas again.

Caption-from-Crowd transition polish

  • Hero photo no longer fades out and back in every 20s during the caption phase.
  • Winner-to-caption handoff now slides the winning tile to the caption layout position before the cloud fades — no more "moves, vanishes, cuts back."
  • Fade-cycling, timer label, and clock reset bugs all fixed.

Other

  • QR overlay no longer clips on launch.
  • Recessed primary groups, brushed-metal hairline on the VFX/Autoplay face plate, FX activity LED.
  • Scroll indicators for multi-column layouts.
  • Mod-section popout toggles clickable.
  • Demo activity prompts locked + submission pools tightened.
1.4.18 May 3, 2026

Phasion Live 1.4.18

Photo pipeline performance overhaul and a cleaner packaged-build menubar.

What's new

Photo pipeline overhaul

The photo flow used to do most of its work synchronously on the Electron main process and on the controls renderer's main thread, which could stall both processes during a photo burst. This release reworks the pipeline end-to-end so the heavy work happens asynchronously, off the hot path:

  • Async disk writessavePhotoToHistory no longer blocks the main process on fs.writeFileSync. The 270 KB JPEG, the history log read, and the history log write are all fs.promises now and run as a fire-and-forget IIFE. The filename is still computed synchronously (pure string ops) so callers can build a localPath immediately.
  • Slim IPC payloadscarousel-photo-added and photocontest-entry no longer carry the full base64 dataUrl through Electron IPC. The receivers read the file off disk via file:// instead. Controls and viz no longer pay a 270 KB JSON.parse on every photo arrival.
  • file:// URLs everywhere — photo overlay, photo-grid thumbnails, carousel thumbs, and the on-screen photo cloud all now use file:// URLs when a localPath is available. The browser loads them asynchronously off the renderer's main thread instead of synchronously decoding base64 strings.
  • Async resize pipeline — when a photo is queued for display, a createImageBitmap + toBlob pipeline runs on worker threads to produce a smaller (max 720 px wide) JPEG blob URL. Smaller bitmaps mean faster GPU texture uploads.
  • Pre-resolved imgSrc — the visible photo overlay sets its <img src> to a pre-decoded blob URL instead of triggering a fresh decode at display time.

Controls window rendering

  • CSS contain: layout paint style + content-visibility: auto on every collapsible section body. Off-screen sections (e.g. the entire Crowd Play panel when scrolled out of view) skip layout entirely; visible sections can no longer cascade reflow into the rest of the window.
  • <img> photo-grid thumbnails — the photo-contest grid in the controls window now uses <img decoding="async"> instead of <canvas> per tile. 2D canvases can be auto-promoted to compositor layers in Chrome; with N tiles in the grid that meant N compositor layers and an expensive Layerize pass on every photo arrival. <img> elements aren't auto-promoted, so adding a tile no longer churns the compositor.
  • Carousel thumbnail strip uses file:// URLs in the <img src> instead of inline base64 dataUrls. Was previously embedding N×270 KB into innerHTML on every photo (parsed by the HTML parser synchronously); now the strip rebuild is essentially free.
  • Analytics log capped at 20 rows (was 50) and isolated with contain: layout paint. Inserts are incremental — no more rebuilding the whole log via innerHTML.

Visualizer window rendering

  • Photo overlay permanent layout#photo-overlay is now permanently display: flex with visibility: hidden while idle, instead of toggling display: none ↔ flex on every photo arrival. The compositor layer is allocated once at page load. Photo arrivals only flip already-allocated layer state — no Layout/Paint/Layerize cascade.
  • Texture warmer — a hidden 1×1 px <img> in both viz and controls pre-uploads each incoming photo's bitmap to the GPU before the visible element paints, so the visible paint is a cache hit.
  • will-change audit — removed from .sub-toast (every toast appearance was creating and tearing down a compositor layer, driving Layerize cost up during photo bursts) while leaving it on persistent compositor-promoted elements like the preview frame.

Packaged-build menubar

  • The Developer menu, the auto-open DevTools at launch, and the Cmd+Alt+Shift+I global shortcut are now all gated to development builds. Packaged release builds ship with a clean menubar and no DevTools entry points exposed to end users.

Misc

  • DevTools menu adds an Open DevTools — Focused Window entry (Cmd+Alt+I) so any window — including popouts — can be inspected.
1.4.17 May 3, 2026

Phasion Live 1.4.17

Major guided-tour rebuild, layout overhaul, output preview reliability, and a long list of polish fixes.

What's new

Guided tour rebuild

  • Step order rewritten to follow the new column layout — Setup (settings) → top toolbar → audience-facing column → operator monitoring (Output Preview, Autoplay, Demo) → moderation + meta
  • Settings window stays open beside the controls window for the entire tour and is left in a clean catalogue layout (all 4 menu-groups expanded, all sections collapsed) when the tour ends
  • Tour windows fill the full display: settings flush to the right edge, controls flush to its left edge, no gaps
  • Tour tooltip no longer flickers/zooms between steps — pre-positioning waits for layout to settle and writes are skip-if-no-change
  • New live demos: simulated lyrics (title, artist, timed lines) for the Lyrics step; pre-fetched QR data URL eliminates the activation freeze on the Audience QR step
  • Output Preview is sticky-pinned at the top of its column during the tour and lifted above the spotlight overlay so demos (poll bars, QR, marquee, photo carousel, emoji rain) are visible while the operator reads the tooltip
  • Visual Effects + Output Preview tour steps removed (self-explanatory)
  • New Autoplay + Demo Mode tour steps with proper deferred-collapse behavior so opening Demo doesn't push the preview off-screen
  • Tour starts from the right Audience tab (Crowd Play) and ends with Output Preview / Audience Activities / Moderation expanded
  • Setup-hint pill in the Output Preview header prompts new operators to pick an output display before their first show

Layout

  • 3-column breakpoint dropped from 1500px to 1100px so the inline preview + 3-col layout fits on more displays
  • Column-resize handles widened from 8px → 18px hit area for easier grab; visible bar stays slim
  • Column widths persist across launches; resize handles re-snap correctly on load
  • Resize-window freeze fixed (rapid Moom/snap-shortcut resizing no longer locks the app)
  • Output Preview body auto-collapses at 2-col widths and auto-restores at 3-col
  • Output Preview wrap maintains 16:9 aspect ratio when manually resized — height drag now scales the preview instead of cropping it
  • Preview captured stream now crops the visualizer's 28px HTML titlebar via object-fit: cover bottom-anchor

Output preview reliability

  • Canvas pixel buffer is now LOCKED to the configured output resolution (no more drift from renderScale at 1080p)
  • New viz-content-ready handshake gates the controls' first preview-stream start until the visualizer window has settled at its configured size — eliminates the "QR appears shifted, hit Apply to fix" startup race
  • Defensive setContentSize re-pins the viz window on did-finish-load to absorb macOS chrome-math drift
  • Pre-fetched QR + poll-QR data URLs eliminate the network-fetch stall that froze the visualizer on the first Show QR / Go Live
  • Pre-warmed GPU compositor layers + removed backdrop-filter from QR/poll overlays + reduced heavy box-shadows = no more ~300ms freeze on first poll/QR activation
  • 280ms IPC-level activation buffer for poll + QR so butterchurn renders smoothly through the activation moment
  • QR + poll fade-up durations bumped to 1.4s for a more graceful entrance

Output resolution & syphon

  • Settings dropdown now restores the saved resolution (was always showing 720p regardless of saved value)
  • set-output-resolution IPC keeps the renderer's canvas in lockstep with the configured output across resolution changes, config-syncs, and Syphon restarts
  • Visualizer renderer pulls config directly via getConfig at startup as the authoritative source, race-free with IPC pushes
  • outputHeight: 1022 issue at 1080p eliminated for the canvas pixel buffer (renderScale no longer multiplies the configured size)

FX keyboard shortcuts

  • Sequential top-row keys for the 9 momentary effects:
  • Space = FLASH, ` = Shake, 1 = Zoom, 2 = Crush, 3 = Blur, 4 = Spin, 5 = Hue, 6 = Squeeze, 7 = Ripple, 8 = Black
  • B = master blackout (panic cut)
  • Black-strobe button now flashes visually when triggered via keyboard (was missing the .strobe-flash class on key 8)
  • The 4 ISF on/off effects (Kaleido / Pixel / Wave / Glitch) intentionally NOT keyboard-bound — they're toggles, not momentary

Emoji applause collapse

  • Operators can collapse the emoji-applause grid from a thin always-visible toggle bar to reclaim ~80px of vertical space
  • Collapsed state persists via config.emojiBarCollapsed

QR overlay

  • Resolution-relative scaling — same qrCustomScale value reads as the same RELATIVE size at 720p and 1080p (was a fixed 272px regardless of canvas, making it look big at 720p and small at 1080p)
  • QR position clamps so the panel can never extend off any canvas edge (a low qrCustomY at 1080p with a resolution-scaled panel was pushing the top ~150px off-canvas, visible as "QR too high")
  • Initial QR placement re-applies on getConfig-driven canvas lock so the panel matches the locked canvas without an Apply round-trip
  • QR fade duration bumped to 1.4s; getComputedStyle is read for the canvas-side opacity so it matches the DOM transition curve

Marquee / scrolling text

  • Position formula is now linear and resolution-agnostic: 0 = top, 50 = center, 100 = bottom-anchored. 100 always touches the bottom edge regardless of canvas size.
  • Default font-size bumped to 60px and default position to 100 for new installs

Moderation panel

  • Tabs styled to match the audience-activities gradient pill treatment
  • Active tab pill is flush with the left edge of the panels above and below it
  • "Hold ALL for Review" panel sits above the tabs as the global override

Misc polish

  • Setup-hint pill (⚠ PICK OUTPUT DISPLAY) in the Output Preview header for first-run operators
  • Exit Fullscreen button is neutral grey (was distracting red)
  • Output preview height persists across launches
  • Demo Mode section restyled to match the Autoplay primary-group treatment (typography, hairlines, decorative line)
  • Settings window content no longer clumps at the bottom with a huge black gap above (#controls-grid was greedily filling the empty viewport in settings mode)
  • Browser button no longer cut off in narrow Crowd Play column (min-width: 0 on the category dropdown)
  • Audience tabs end-of-tour state correctly displays the active panel without needing a manual click

Bug fixes

  • Resolution dropdown in settings now reflects the saved resolution on open
  • App no longer freezes when window is rapidly resized at certain widths (replaced ResizeObserver feedback loops with window.resize listeners)
  • setlistCuedIdx no longer greys out past scenes when clicking a stopped setlist
  • Output Preview popout no longer crashes due to desktopCapturer legacy flag conflict
  • Setlist scroll trapping removed
  • Demo seeder cleanup waits on slug equality so stale callbacks don't fire after Stop
  • Multiple ResizeObserver feedback loops eliminated during rapid window resize
1.4.16 May 2, 2026

Phasion Live 1.4.16

End-of-night recap system, photo collection refinements, and moderation popout fixes.

What's new

End-of-night recap

  • Operator wrap-up flow with End the Night button and audience-page takeover
  • /recap page served via Cloudflare tunnel — scan the on-screen QR to access from off-network
  • Recap show loops on the visualizer until manually stopped, with prompt + author byline on top-phrase slides and a centered QR on the outro
  • Photo mosaic + carousel social-pack export with four aspect ratios; bulk per-activity word-cloud export ("each activity, separate files")
  • Branded photo downloads with venue caption strip; iOS Save-to-Photos via Web Share API
  • In-app photo report flow with required reasons + quick-tap chips, replacing email reporting
  • Reported photos are locked from download and show a "REPORTED — PENDING REVIEW" overlay; SSE broadcast drops the card on live audience pages when the operator approves removal
  • Reopen Submissions button rolls the night back if you ended it by mistake — audience pages auto-redirect back

Photo collections

  • Built-in samples collection — the 12 bundled photos always available as a permanent read-only library, even after switching away to a custom collection
  • Active scenes can bind to a collection — activating the scene loads it into the carousel
  • Loading a collection collapses the editor's preview row (the carousel strip below shows the same photos)
  • Audience photos approved while a collection is active still append to the carousel for the night; switching collections replaces the set but leaves history intact

Moderation

  • The Moderation popout now respects your saved collapsed state for the four sub-sections (Messages / Photos / AI Prompts / Crowd Play) and persists collapse changes you make from inside the popout
  • Default popout heights tuned: Moderation (363px) and Analytics (842px) match real-world use

Seeded content

  • Installer now ships your current scenes.json, setlists.json, and preset-config.json plus the 12 built-in photos as starter content for new installs

Bug fixes

  • Word cloud no longer animates spastically on the recap show (placement is now cached per moment)
  • QR code on the outro slide is now vertically centered between the brand and "thanks for tonight" lines
  • iOS Save-to-Photos now works for branded photo downloads (rasterize-SVG-first pattern)
  • _startCarousel was reading from photo-history and missed collection files — now uses collectionLoadPhotos when a collection is active
1.4.15 May 1, 2026

Photo Collections, Remote Activity Creation, Scene MIDI/OSC Triggers, Scroll Indicators, Demo Polish

1.4.14 Apr 28, 2026

Phasion Live 1.4.14

Hot-fix for 1.4.13.

What was broken

defaultScenes.js exported module.exports = { DEFAULT_SCENES } (object wrapper) but main.js does const DEFAULT_SCENES = require('./defaultScenes') (expects the array directly). Result: loadScenes() threw TypeError: defaults is not iterable on every IPC call from the renderer, the scene list silently failed to populate, and you saw "No scenes yet" even when scenes.json on disk had scenes.

What's fixed

defaultScenes.js now exports the array directly (module.exports = DEFAULT_SCENES), matching the contract main.js has used since the default-scene infrastructure was first introduced. After update, loadScenes succeeds and you'll see all your scenes plus any defaults that should be merged in.

Heads-up

If you've been on 1.4.13 since this morning, you may have a backup scenes.json.backup-* file in ~/Library/Application Support/Phasion Live/ from a recovery attempt. Once 1.4.14 lands and your scenes are back, you can delete that backup. Your live scenes.json is the authoritative file.

1.4.13 Apr 28, 2026

Phasion Live 1.4.13

The biggest release since the rebrand. Crowd Play graduates into a full scene-driven feature, the guided tour gets four live demos, the scene editor learns about activities, and a complete OnlyJams-themed default content kit ships with the app.

What's new

Crowd Play in scenes

  • New scene.config.crowdPlay schema with stable activity slugs.

Same slug across scenes = same continuous activity — submissions, votes, photo entries persist across the swap. Audience phones don't reconnect.

  • Smart-replace activation: activating a scene carries forward

matching slugs, soft-stops non-matching ones with a graceful fade, and starts brand-new ones. keepPriorActivitiesRunning flag opt-in for transition / ambient scenes that should stack.

  • Per-scene Crowd Play editor in the layer panel — add up to 4

activities (Open Mic / Roast / Compliment / Hot Take / Caption Contest / Photo Contest / Pet Contest), pick a spotlight, edit prompt + photo + moderation + palette + carousel inline. Advanced disclosure surfaces palette / prompt style / size / QR / audio reactivity.

  • Preset-aware fields: photo picker only on Caption Contest, mode

override only on tone presets, Photo Contest gets a Mosaic vs. Carousel display toggle.

  • Replace-vs-Add prompt: activating a scene over running

activities asks the operator whether to replace or layer on top. Setlists bypass via opts.force.

  • Photo gate: Caption Contest scenes without a pre-pinned photo

jump the operator to the live photo strip + Upload button on activation. Pick from audience submissions or import — every activation re-prompts so each session can use a fresh photo.

Scene Wizard upgrades

  • Renamed Create Scene✨ Scene Wizard and added a `🗒 Blank

Scene` button next to it for the "I'll author from scratch" path.

  • Wizard's Extras step gets a Crowd Play row (preset dropdown — pick

one to scaffold). Mutually exclusive with Trivia Auto-play.

  • Scene name input now has a 😀 emoji picker — same palette the

inline-rename uses, with Crowd Play activity icons added.

Guided tour overhaul

  • Re-sequenced the audience-engagement steps: gateway → Crowd Play →

AI → Moderation → Trivia / Poll / Applause → passive overlays.

  • Demos refactored to a string-keyed registry — adding / reordering

steps no longer requires re-numbering switch cases.

  • New live demos:
  • Crowd Play step: a fake Open Mic with 16 curated audience

submissions floating onto the screen. Scatters off-screen with spin + decay when you click Next.

  • AI Visuals step: a pre-rendered demo image with the prompt

caption, lifted right out of the live audience-submission flow.

  • Live Poll: panel now fades in over 750ms (was an abrupt

pop-in).

Whitelabel branding

  • Section now properly license-gated — locks for non-licensed users

with a dimmed body, disabled controls, and an upgrade banner that jumps to the License section.

  • New Load demo branding button (licensed users): one-click loader

for a bundled OnlyJams template — useful as a starting point or to see the system fully configured.

Bundled default content

  • 17 default scenes ship in the box (was 5): the full set covers

Pure Visuals, Walk-In, Peak Hour, Sponsor Loop, Desktop Mix, Audience Photos, AI Art Gallery, Karaoke Night, Trivia Night, Conference / Talk, plus all 7 Crowd Play activities (Caption Contest, Photo Contest, Pet Photo Contest, Open Mic, Roast, Compliment, Hot Take).

  • Scene logos seeded from bundled assets — fresh installs get the

full visual experience without manual logo uploads.

  • Demo branding kit (logo + config) shipped at

assets/demo-branding/ for licensed users to load on demand.

Polish

  • Audience page no longer flickers the AI prompt tab — operator-side

push gates aiActive on the master checkbox AND running flag, audience-side tab gates require both aiActive AND aiAudienceAllowed consistently.

  • Lyrics overlay shows the song title even when the recognized track

has no synced lyrics (instrumentals, rare tracks, lyric-provider misses).

  • Header narrow-mode behavior: selectors stop truncating at full

width, perf-pill + theme drop at ≤1200px so the panic-button (⬛) always survives.

  • Perf-pill is now tap-to-reveal-FPS at narrow widths.
  • Photo Contest QR safe-rect now also avoids the WC canvas-drawn QR

card. Photos no longer leak past their parent activity on scene swaps. Caption Contest carousel polish across the board.

  • Audience Activities menu group gets its 🙌 emoji.

Upgrading

Drop the new DMG over the old install. Your scenes, branding, and license carry over. The new default scenes get merged in alongside your existing ones (any of yours with the same name is unaffected). Your existing branding is untouched — the Load demo branding button is opt-in.

1.4.12 Apr 23, 2026

Phasion Live 1.4.12

A big live-ops and post-show polish pass. The Controls window learned a proper command palette, a keyboard-shortcut sheet, a master "hold everything" panic control, and four new export formats — including a shareable HTML recap page and 9:16 PNG cards for Instagram Stories, Reels, and TikTok.

New

Submission Activity toast stack

Every audience submission now surfaces as a quiet toast in the bottom-left corner — separate from the system toast stack so warnings don't get buried in chatter. Each kind has its own emoji (💬 message, 🖼 photo, 🎨 AI prompt, 🏆 contest entry, 🧠 trivia, 📊 poll, etc.), photos awaiting moderation get an amber "pending" border, and the stack auto-dismisses after 2.5s with a 4-toast visible cap. Toggleable from the Analytics session bar if you ever want silence during a busy set.

🛡 Hold ALL for Review — master moderation panic control

A single command pauses every audience channel at once (messages, photos, AI prompts, photo contest). When released, every channel goes back to the exact moderation setting you had before — no manual re-configuration required. Lives in its own row at the top of the Moderation section, with a clear engage/release CTA. Active state pulses red and a full-width banner at the top of the window stays visible from anywhere so you can release with one click even if the Moderation section is collapsed. Keybind: H. Also in ⌘K.

⌘K Command Palette

A search-anywhere overlay with fuzzy matching, keyboard navigation (↑ ↓ ↵), grouped results, and a rolling "Recents" section. Covers:

  • Jump to scene — type any scene name
  • Jump to section — 14 Controls sections (Moderation, Feeds, Analytics, Word Cloud, etc.)
  • Global commands — Hold for Review, Blackout, Toggle Theme, Open Settings, Show Shortcuts, End Trivia/Poll, Generate Recap, Export CSV/JSON, Export Social Cards
  • Show Keyboard Shortcuts — opens the cheat sheet

Open with ⌘K / Ctrl+K, or the 🔍 Search button in the header.

? Keyboard Shortcuts cheat sheet

Press ? (or find it via ⌘K) to see every shortcut grouped by category — Output, FX Triggers, Audience/Safety, Navigation, Appearance, Help. New keybinds added in this release:

  • H — Toggle Hold for Review
  • T — Toggle theme
  • ⌘, — Open Settings window
  • ⌘0⌘9 — Jump to scene slot 1–10
  • ? — Show this sheet
  • Esc — Close palette / sheet

All typing-safe (won't fire while you're in a text field).

Session Recap page (shareable HTML)

A single self-contained HTML file the VJ can AirDrop to their phone, email to the venue, or upload to their own site — no external dependencies, no server required. Includes:

  • Hero banner with session date, start time, duration, total interactions
  • Stat cards for Submissions · Reactions · Poll Votes · Trivia Answers
  • SVG activity sparkline showing the arc of the night + peak annotation
  • Top 8 reactions with proportional bars
  • Top 3 photo-contest winners inline (base64-embedded, sorted by votes, captions + bylines)
  • Up to 24 most-recent audience words as chips
  • Top 10 trivia teams with 🏆 for #1
  • @media print styles so ⌘P → PDF works as a printable keepsake

Opens in your default browser automatically after save.

Social Cards — 1080×1920 PNG set for Stories / Reels / TikTok

Pick a folder and Phasion generates up to 5 post-ready vertical cards:

  • Hero — huge total-interactions number with brand gradient
  • Top Reaction — giant emoji + count
  • Top Photo — winning entry full-bleed with caption, byline, vote badge
  • Audience Words — top submissions size-ramped by recency
  • Trivia Champion — trophy + team name + final score + runners-up

Each card auto-hides if it has no data, respects IG Stories safe zones (top/bottom 14% reserved for profile pic + swipe-up), and includes a Phasion Live watermark. Finder opens to the output folder automatically.

Session data export — CSV + JSON

Two new buttons next to the existing clipboard report:

  • 📊 CSV — one row per event with timestamp, time-of-day, elapsed seconds, type, subtype, content, author, slug, emoji, trivia choice + correctness, pending flag. RFC-4180 quoting survives multi-line captions in Excel and Sheets.
  • 🧾 JSON — full session payload: start time, duration, counts, emojiCounts, minute-buckets, and the full event timeline. format: "phasion-live-session", version: 1 header for future compatibility.

Both reachable from ⌘K.

Under the hood

  • Timeline schema now captures content. The analytics timeline stored only {ts, type} before — now it carries subtype, text, author, emoji, slug, pending, choice, and correct when applicable, which is what makes the CSV/JSON/recap/social exports actually useful.
  • Missing ingress logging fixed. Photo Contest entries, pending photos, and carousel photos weren't being recorded at all — now they flow through analyticsRecord() like every other submission type.
  • New writeBinaryFile IPC for rendering PNGs from Canvas off-screen and persisting them via the main process.

Fixes

Photo Contest entries no longer leak into the Photo Carousel

Before this, every Photo Contest submission was also being pushed into the general Photo Carousel rotator — so the carousel would end up full of contest entries even when you weren't running a carousel scene. Fixed so contest entries stay in the contest flow (their own grid, review, and winner overlay) and never pollute the carousel.

"Scan to enter the Photo Contest" poster no longer lingers after Stop

When a Photo Contest scene was stopped, the empty-state poster would sometimes stay on screen. Now gated on both mode === 'photos' AND enabled === true, and the overlay element is explicitly cleared on the exit fade — so Stop is Stop.

Upgrade path

The auto-updater in 1.4.11 will pick this up on its next check. No action needed.

1.4.11 Apr 22, 2026

Highlights

Word Cloud scene. New scene renders the audience/custom/feed text stream as frequency-sized words, floating phrases, or both simultaneously. Ships with 8 palettes (neon, sunset, ocean, mono, pastel, cyberpunk, fire, rainbow) plus a scene-accent option, audio-reactive sizing, and a QR overlay for audience submissions.

Live Now feed + word cloud moderation. Activity feed for word cloud events. Moderation adds voter ban, automatic slur flagging, and per-submission delete. Hot Takes gains an undo toast, ban count, and title badge.

Content-addressable asset store. Embedded logos and carousel thumbnails are now stored once on disk and referenced by SHA. Existing installs see \scenes.json\ shrink from ~41 MB to ~44 KB and \preset-config.json\ from ~16 MB to ~36 KB on first launch. Fully automatic — no user action needed.

Starter content out of the box. Fresh installs launch with 10 demo scenes, 5 example logos, and 12 carousel photos pre-loaded so every feature works without setup.

Branding cleanup. User-visible \"AV Club VJ\" strings renamed to Phasion Live throughout.

Fixes

  • WC delete no longer wipes the whole slug's live buffer
  • WC activity QR now routes to the unified audience page

Misc

  • Launch a browser at startup (Settings → Media Capture)
  • Default-scene deletions now persist across restarts
  • \"Classic\" word cloud preset renamed to \"Open Mic\"
  • Repo-root PNGs reorganized into \assets-src/{photos,logos,installer}/\