Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion quest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ there first. A quest here that needs it waits on a pin quest, which
## Required

- [m0: the studio](/quest/m0/README.md) - the native studio for creators who rely on OBS today
- [m1: after the studio ships](/quest/m1/README.md) - studio features held past m0; empty now
- [m1: after the studio ships](/quest/m1/README.md) - what the redesigned studio gains, and the way in from OBS
- [m2: later](/quest/m2/README.md) - work with no consumer yet
- [m3: someday](/quest/m3/README.md) - work no customer asks for, kept so its plans are not lost
9 changes: 9 additions & 0 deletions quest/m0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ replanned 2026-11-08 around independently published sources layered over the
program). Overlays and animation render into the program here; that epic's
layout track carries only the layers of independently published sources.

Changed 2026-11-09 with the maintainer (/quest-plan): the studio gets one
designed layout, a live picture with pages around it, in place of sixteen
dockable panels; see [Broadcaster UX](/quest/m0/ux/README.md). Docking no
longer argues for a toolkit, so that epic's spike decides it again between
egui and Slint, the two that draw the compositor's textures with no copy on
the studio's own device.

Dropped from the first scoping round: relay fan-out ("encode once, the relay
restreams") and its upload savings. Direct push with shared encoders matches
OBS multistream, and the hosted version is product work outside this
Expand All @@ -104,6 +111,8 @@ repository.
- [Browser sources on macOS and Windows](/quest/m0/browser-source/README.md) - the out-of-process CEF pages Linux has, with shared GPU textures on the other desktops
- [Virtual camera](/quest/m0/vcam/README.md) - the program or a published scene exposed as a system camera on Linux, Windows, and macOS
- [The Apple signing identity is available](/quest/m0/signing.md) - the Apple credentials the macOS app and its camera need; Windows ships unsigned
- [Broadcaster UX](/quest/m0/ux/README.md) - one live picture with pages around it, in place of the dock of panels and the launch flags
- [moq-video's capture listing is pinned](/quest/m0/pin-capture-list.md) - icons and live pictures of windows and devices, for the Add page
- [Packaging](/quest/m0/packaging/README.md) - a signed macOS app, a Windows installer, and a Flatpak for Linux, each its own quest
- [The persistable portal restore token is pinned](/quest/m0/pin-portal-token.md) - moq-video's restore token, for Wayland sources
- [Platform AAC encoders are pinned](/quest/m0/pin-aac-encode.md) - moq-audio's AAC encoders, for AAC destinations
Expand Down
13 changes: 10 additions & 3 deletions quest/m0/destinations.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
A creator adds any number of RTMP, RTMPS, and WHIP destinations alongside
MoQ, each with its own codec and bitrate, and goes live to all of them at
once. Destinations that take the same picture scene and audio scene with identical
encode settings share one encoder. Each destination's status and errors show
in the UI. Going live and stopping are actions the Hotkeys panel can bind,
as recording is. Audio is Opus here; AAC is
encode settings share one encoder. Each destination is a row in the go-live
sheet and in the health dot's list, with its status and errors. Audio is Opus
here; AAC is
[AAC for destinations](/quest/m0/destinations-aac.md).

The fan-out lands here as a UI-free egress library, with the studio as its
Expand Down Expand Up @@ -72,8 +72,15 @@ Decided 2026-11-09 (maintainer, /quest-audit):
here, with no moq quest or pin). This quest uses them through
[the pin](/quest/m0/pin-egress-dial.md).

Changed 2026-11-09 (maintainer, /quest-plan): going live and stopping, as
actions and as hotkeys, are
[Going live from inside the app](/quest/m0/ux/go-live.md), which lands them
for MoQ relays. This quest adds its destinations to that sheet rather than
building a second way to start a stream.

## Required

- [Going live from inside the app](/quest/m0/ux/go-live.md) - the go-live sheet, the live control, and the health list its destinations join
- [moq's egress dial changes are pinned](/quest/m0/pin-egress-dial.md) - RTMPS that keeps `tcUrl`, and a dial policy the caller supplies

## Related
Expand Down
23 changes: 23 additions & 0 deletions quest/m0/pin-capture-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# [XS] moq-video's capture listing is pinned

## Goal

The `moq` submodule includes moq-video's richer capture listing: each window
and app with its icon and a stable identity, a live thumbnail of a window,
display, or camera without adding it as a source, and a notice when the list
changes.

## Plan

Planned 2026-11-09 (maintainer, /quest-plan) for the
[Add page](/quest/m0/ux/add.md), which shows pictures where the Devices panel
shows names. Advance it with `just upgrade-moq` in its own PR, fixing whatever
the new API breaks in `rs/moq-studio/src/devices.rs`.

## Waiting

- moq-dev/moq: [the capture listing quest](https://github.com/moq-dev/moq/blob/main/quest/m3/capture-list.md) lands on moq's `main`. Check that quest's PR has merged.

## Required

- [The studio is caught up to moq's main](/quest/m0/pin-main.md) - moq's breaking changes since moq-dev/moq#8272, so this pin takes only its own
147 changes: 147 additions & 0 deletions quest/m0/ux/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Broadcaster UX

## Goal

A broadcaster opens the studio to one live picture, with the scenes, the sound
levels, the state of the stream, and a panic key always on screen. Everything
else is on a page, in the selected layer's inspector, or in Settings, and an
edit changes what is on air. An optional Studio mode adds cue and take for
broadcast operators.

It replaces sixteen dockable text panels, a Preview and Program pair, and
command-line flags for what a broadcaster must set before going live.

Non-goals: media or protocol work, which stays in moq; a plugin API; and
integrations built on any one platform's API. Chat, activity, and dashboards
reach the studio as [private panels](/quest/m1/panels.md), any web page shown
beside the show and never in it.

This README's own work, once every child has merged: `README.md`'s Panels
section is rewritten around the pages, with a picture of each from the
[screenshots](/quest/m0/ux/shots.md), and the maintainer runs one real show
start to finish on the finished UI.

## Plan

Decided 2026-11-09 with the maintainer (/quest-plan). The mock-ups in
[`mock/`](/quest/m0/ux/mock/shell.html) are the reference for every child: HTML
pages drawn at 1440x900, each frame rendered beside it as
`<page>-<frame>.webp` by `mock/render.sh`. They fix layout, hierarchy, and
tone. The app is native, so a child matches them in what is where and how it
reads, not pixel for pixel, and a child that has to depart from one changes
the mock-up in the same PR.

![LIVE](/quest/m0/ux/mock/shell-live.webp)

### Decisions

- **Shape:** ✅ one live picture with pages around it (rejected: a hardware
console under the picture, which spends a third of the window on controls a
solo streamer drives by hotkey; workspaces that lock editing on the live
page; a restyle of today's panels).
- **Pages:** ✅ LIVE, BUILD, MIX, and REVIEW (rejected: a left rail of
drawers). They sit in the title bar when the show is landscape and in a left
sidebar when it is portrait, where the spare room is (rejected: always along
the bottom, which costs a landscape picture its height).
- **Live editing:** ✅ no Preview monitor. A scene click takes that scene, and
an edit applies on air. Any scene can be opened for editing off air: the
frame turns amber, the live picture shrinks to a corner, and one button
takes it live or goes back.
- **Studio mode:** ✅ cue and take, off by default (rejected: a Preview and
Program split, which halves the live picture; no mode at all). A scene click
cues, and TAKE or AUTO puts it on air.
- **One control per state:** the live control reads LIVE with the clock and
becomes END STREAM under the pointer. One health dot stands for every
destination, the viewers, and the encoder, which its hover lists. Undo,
record, and settings are icons with tooltips.
- **Not on the home page:** the format, canvas size, and frame rate, which a
broadcaster sets once. They live in Settings.
- **Panels:** ✅ chat and other private panels are their own windows, hidden
from capture, dockable into spare room but never docked by default
(rejected: a chat column in the main window; leaving chat to the browser).
- **Formats:** ✅ one format per show in m0, landscape or portrait, and the
layout follows it. [Both at once](/quest/m1/dual-format.md) is m1 (rejected:
designing every m0 page for two pictures).
- **Layout follows the picture:** the picture gets the largest rectangle the
window allows, and the scenes and the sound take whichever side is left
over. See the portrait and half-screen frames.
- **Toolkit:** ✅ decided by [a spike](/quest/m0/ux/spike.md) of the LIVE page
in egui and in Slint before any page is built (rejected: staying on egui
unasked; egui against Rune, which
[moq-dev/studio#98](https://github.com/moq-dev/studio/pull/98) already
spiked). Only those two draw the compositor's own textures with no copy on
the studio's own device today.
- **Milestones:** ✅ redesigning what exists is m0, here. Features that do not
exist yet are [m1](/quest/m1/README.md), and three more are
[m2](/quest/m2/README.md) (rejected: all in m0; all in m1).
- **Dropped:** a rundown that fills overlays, one-click looks and a brand kit,
active-speaker layouts, control surfaces, and a rehearsal mode. Not planned.

### What is where

The first column holds on every page, not only LIVE. The bottom strip of
scene pads, panic key, and sound is on all four. On MIX, which is the sound,
its sound slot holds a small live picture instead, and on REVIEW the
program's card is the live picture.

| Always on screen | On a page | In Settings |
| --- | --- | --- |
| The live picture and its tally frame | BUILD: layers, adding a source, the inspector, keyframes | Format, canvas size, frame rate, scene sizes |
| Scene pads with live thumbnails | MIX: every strip, sends, filters, delay | Where the stream goes, keys, failover |
| A meter and a mute for each sound on air | REVIEW: replay, clips, recordings | Recording folder and contents |
| The live control, health dot, and record | Health details, from the health dot | Hotkeys, virtual camera, guests' room |
| The panic key | Guests, from Add | Effects, published scenes, the scene graph, edit history |

### The frames

| Frame | Shows |
| --- | --- |
| [live](/quest/m0/ux/mock/shell-live.webp), [hover](/quest/m0/ux/mock/shell-hover.webp) | The LIVE page, and what the health dot, the live control, and an icon show under the pointer |
| [build](/quest/m0/ux/mock/shell-build.webp), [offair](/quest/m0/ux/mock/shell-offair.webp) | The BUILD page on air, and editing a scene that is not |
| [studio](/quest/m0/ux/mock/shell-studio.webp) | Studio mode: a cued scene, NEXT, TAKE, and AUTO |
| [portrait](/quest/m0/ux/mock/shell-portrait.webp), [compact](/quest/m0/ux/mock/shell-compact.webp) | The layout following a portrait show, and a window snapped beside a game |

`add.html`, `firstrun.html`, `mix.html`, `settings.html`, `review.html`, and
`golive.html` hold the other m0 pages, and `later.html` the m1 features; each
quest links its own.

### Borrowed

- Editing the live picture, with layers beside it: Meld Studio and StreamYard,
which stay safe by constraining what a click can do.
- Cue and take, red for program and amber for preview: hardware switchers.
vMix and OBS Studio Mode show the cost of the split this plan rejects.
- Selection handles, smart guides, a toolbar on the selected thing, and an
inspector that follows the selection: Figma and Keynote.
- Pages for kinds of work: DaVinci Resolve.
- Sends as a matrix of sounds against mixes: Wave Link.
- The first-run format choice before any scene exists: mobile-first studios.
- OBS 32.2's add-source dialog with thumbnails, which this goes past with app
icons and live pictures.

### What a person must check

An agent can prove a page matches its mock-up's layout, that nothing clips at
any window size, and what a frame costs. It cannot judge these, so each child's
PR hands them to the maintainer as `## Waiting` with what to look at:

- **Taste:** whether the page reads as bold and calm at once. The PR shows its
screenshots beside the mock-up frames.
- **Feel:** drag latency, how a scene change and a tally change move, the hold
to end a stream. The PR attaches a short recording, and the maintainer tries
it on their own machine.
- **Real devices:** cameras, capture cards, microphones, a second monitor, and
mixed display scales. The agent hosts have no camera.
- **System dialogs:** permission prompts and the operating system's own window
pickers, which no headless run can answer.
- **A real stream:** going live to a real destination with the maintainer's
credentials, and ending it.
- **Other apps in front:** hotkeys, and later the mini controller, while a
full-screen game has focus.
- **Readability:** contrast, and red against amber for a color-blind reader.

## Related

- [m1](/quest/m1/README.md) - the features that follow the redesign
- [Destinations](/quest/m0/destinations.md) - RTMP and WHIP rows in the go-live sheet this epic builds
- [Wayland display and window sources](/quest/m0/wayland-sources.md) - the system picker the Add page opens
63 changes: 63 additions & 0 deletions quest/m0/ux/add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# [L] Adding a source by picking a picture

## Goal

BUILD's Add tab shows what can be added as pictures, in the frames of
[`mock/add.html`](/quest/m0/ux/mock/add.html):

- **Apps:** every window as a live thumbnail with its app's real icon, its
app's name, and its title, grouped by app.
- **Screens and cameras:** a live picture of each, with an icon for the kind
of device (webcam, capture card, phone, display) and its name.
- **Sound:** each microphone and the system's sound with a moving meter, so
the right one is found by talking.
- **Everything else:** files, a web page, text, guests, and other scenes,
each a card.

A search field filters all of it, and a Recent row holds what was added
lately. A card is added by dragging it onto the picture, where it lands under
the pointer, or by selecting it and pressing one Add button. The list
refreshes itself when a device is plugged in or a window opens. No id is ever
typed.

It replaces the Devices panel and the add-source form, where a window is
chosen by typing its id.

## Plan

- The pictures and icons come from moq-video's capture listing, which today
gives only ids, names, and sizes (`Window { id, title, app, width, height }`
in `moq/rs/moq-video/src/capture/mod.rs`), with no icon, no thumbnail, no
change notice, and apps listed on macOS alone. That work is planned in moq
and reaches here through [its pin](/quest/m0/pin-capture-list.md).
- Where the operating system owns the picker, as on Wayland, the Apps and
Screens sections are one button that opens the system's picker, and the
choice is remembered: see the `system` frame and
[Wayland sources](/quest/m0/wayland-sources.md).
- Recommended, not decided: a click selects and a button adds, rather than a
click adding at once. A new layer is on air the moment it is added, and the
selected card's picture is the last check against airing the wrong window.
- The inspector folds away while Add is open, since nothing is selected, so
the picture keeps its width.
- The `apps` frame draws a "With its sound" switch. An app's own sound is not
captured today, so the switch is left out until moq can.
- A card for something that cannot be added says why in its place (a kind
this build lacks, a permission not granted) with the step that fixes it,
rather than being absent.
- A dropped card lands where it is dropped, sized to its own shape, and is
sent to the audio scene on program if it has sound, as an added source is
today.
- The first-run screen reuses these cards.

Human check: real cameras, capture cards, and microphones, the operating
system's permission prompts, and whether a window is found faster than by
its title.

## Required

- [The BUILD page](/quest/m0/ux/build.md) - the column the Add tab lives in
- [moq-video's capture listing is pinned](/quest/m0/pin-capture-list.md) - icons, live pictures, and change notices for windows and devices

## Related

- [Wayland display and window sources](/quest/m0/wayland-sources.md) - the remembered system pick the Apps and Screens sections open
54 changes: 54 additions & 0 deletions quest/m0/ux/build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# [L] The BUILD page

## Goal

The BUILD page of the [mock-up](/quest/m0/ux/mock/shell-build.webp) replaces
the Items, Sources, Filters, and Keyframes panels:

- **Layers** on the left list what the scene draws, front to back, with the
always-on-top layers in a group of their own. Each row has an icon for its
kind, its name, what it shows in words, and eye and lock toggles. Rows drag
to reorder.
- **The picture** is edited directly. A selected layer has handles and a
small toolbar on it (crop, fit, fill, shape, cut out, more), and a right
click anywhere offers what applies there.
- **The inspector** on the right follows the selection: place, shape, look
(background removal, color grade, filters, blend), and an Animate tab that
holds the layer's keyframes.
- **Linked or independent is visible:** a layer that shows a source other
scenes also show says so, with how many, and offers to make it
independent. Duplicating a scene asks which.

Undo and redo are the title bar's icons, and the history is a list under the
undo icon. The scene graph moves to Settings, Advanced.

## Plan

The words change with the place: "item" becomes "layer" and "top layer"
becomes "always on top" in the UI and in `README.md`. The scene file's keys
do not change.

- A source nothing shows no longer needs a panel of its own: Layers lists
the scene's layers, and unused sources appear under Add, where a source is
also removed for good.
- "Make independent" is today's clone (`kind = "clone"`). OBS users lose
work to the opposite default, where a duplicate silently shares its
sources, so say which one a duplicate will be before it happens.
- Every status a source has today (live, stalled, ended, failed with its
reason, GPU or CPU for a web page, the delay a broadcast plays behind)
shows on its layer row as an icon with the words on hover, and Play, Stop,
and Reload are in its inspector.
- Snapping, the grid, nudging, aspect lock, and copy and paste keep working
as `interact.rs` and `snap.rs` have them. Add the right-click menus and the
on-picture toolbar; there is no context menu anywhere today.
- Errors that were one status-bar line (`Panels::message`) appear where they
happened: on the layer, the field, or the pad.
- **Interact** with a web page becomes a mode of the selected layer, entered
from its toolbar and left with Escape.

Human check: feel of dragging, resizing, and reordering on a real machine,
and whether the inspector's grouping is where a streamer looks first.

## Required

- [One live picture](/quest/m0/ux/live.md) - the frame, the stage, and the page this fills
Loading