Skip to content

Add Qt dock UI for MoQ streaming#41

Merged
kixelated merged 3 commits into
mainfrom
claude/magical-mirzakhani-ee5815
Jun 18, 2026
Merged

Add Qt dock UI for MoQ streaming#41
kixelated merged 3 commits into
mainfrom
claude/magical-mirzakhani-ee5815

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

What

Adds a dockable MoQ panel to OBS that drives the MoQ output directly, so the plugin is usable from the UI on stable OBS today.

Why

OBS's stable Settings → Stream UI doesn't surface third-party services (that's pending obsproject/obs-studio#12911), so the registered MoQ service/output were invisible in the UI. A frontend-API dock sidesteps that entirely by creating and starting the output itself.

What's in the dock (src/moq-dock.cpp / .h)

  • Registered via obs_frontend_add_dock_by_id; appears under the Docks menu as MoQ.
  • Relay URL + Broadcast path fields (labels above the inputs for full width), plus a colored Go Live / Stop button.
  • Reuses OBS's configured stream encoders — reads obs_frontend_get_profile_config() and mirrors OBS's Simple/Advanced logic (encoder id, bitrate, preset, audio encoder/track). No encoder options are exposed in the dock.
  • Persists URL/path via obs_module_config_path("dock.json").
  • Live statistics (updated every second from the output object): status, duration, bitrate, data sent, dropped frames, connect time.
  • Bundled libmoq version shown greyed in the corner (from MOQ_VERSION, since libmoq exports no version API).

Build changes

  • Flip ENABLE_FRONTEND_API / ENABLE_QT on in the preset template. The dock only compiles when both are set (gated by MOQ_FRONTEND_ENABLED).
  • AGL workaround (CMakeLists.txt): recent macOS SDKs ship no linkable AGL binary (it lives only in the runtime dyld shared cache), but the obs-deps Qt6 build references AGL transitively via WrapOpenGL. We generate a stub dylib whose install name points at the real framework so the link succeeds and dyld resolves AGL at load. Fully guarded (APPLE + SDK-missing-AGL), so it's a no-op elsewhere.

Testing

  • Builds clean against libobs 31.1.1 (just build, macOS arm64).
  • Installed to ~/Library/Application Support/obs-studio/plugins/ and loaded successfully in stable OBS 31.1.2 — module appears under Loaded Modules, no crashes, Qt runtime 6.8.3 matches build.

Notes for reviewers

  • The Simple-mode encoder-id mapping table mirrors OBS's internal table and may need updates if OBS renames encoder ids across versions (NVENC ids in particular).
  • Stats are OBS-output-side counters; true MoQ-session stats (RTT/congestion/per-track) would require new libmoq FFI exports.
  • Pre-existing just check clang-format step fails only on a tool version mismatch (local 21.x vs pinned ≤19.1.1), unrelated to this change.

🤖 Generated with Claude Code

OBS's stable Settings -> Stream UI does not surface third-party services
(pending obsproject/obs-studio#12911), so the registered MoQ service/output
are invisible in the UI. Add a dockable panel that drives the MoQ output
directly instead, working on stable OBS today.

The dock (moq-dock.cpp/h, registered via obs_frontend_add_dock_by_id) lets
the user enter a relay URL and broadcast path and start/stop streaming. It
creates its own service/output and reuses the encoders configured in OBS's
Output settings (both Simple and Advanced modes), so no encoder options are
exposed in the dock. Settings persist via obs_module_config_path, and a live
statistics panel shows status, duration, bitrate, data sent, dropped frames,
and connect time. The bundled libmoq version is shown from MOQ_VERSION.

Enable ENABLE_FRONTEND_API and ENABLE_QT (gated so the dock only builds when
both are on, via MOQ_FRONTEND_ENABLED). Add a build-time workaround for the
AGL framework: recent macOS SDKs ship no linkable AGL binary (it exists only
in the runtime dyld shared cache), but the obs-deps Qt6 build references it
transitively via WrapOpenGL; generate a stub whose install name points at the
real framework so the link succeeds and dyld resolves AGL at load.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kixelated, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 12 minutes and 7 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d75bbf1d-a37a-4376-be03-c8c9623e0c90

📥 Commits

Reviewing files that changed from the base of the PR and between 5f5c0e2 and 9882f25.

📒 Files selected for processing (3)
  • CMakeLists.txt
  • src/moq-dock.cpp
  • src/moq-dock.h

Walkthrough

This pull request adds a Qt-based OBS dock widget for MoQ streaming. The build system gains a macOS AGL framework stub generator in CMakeLists.txt and enables ENABLE_FRONTEND_API/ENABLE_QT in CMakePresets.json. When both flags are set, src/moq-dock.cpp and src/moq-dock.h are compiled into obs-moq with MOQ_FRONTEND_ENABLED defined. The new MoQDock widget provides relay URL/path inputs, a Go Live button, live statistics display (bitrate, duration, sent MB, dropped frames), encoder selection from the active OBS profile supporting both Simple and Advanced output modes, settings persistence via dock.json, and thread-safe output-stopped signal handling. The dock is registered with OBS via register_moq_dock() called from obs_module_load().

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.05% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a Qt dock UI for MoQ streaming, which is the primary objective of this PR.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering what was added, why it was needed, implementation details, build changes, testing, and reviewer notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/magical-mirzakhani-ee5815

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/moq-dock.cpp`:
- Around line 327-343: The SetRunning method unconditionally sets the status
text to "Idle" when isRunning becomes false, which overwrites any error message
previously set by OnOutputStopped. To fix this, modify the SetRunning method to
preserve the existing status message if it indicates a stopped/error state
(contains "Stopped" or error information), and only set it to "Idle" when it's a
normal stop rather than an error condition. Alternatively, add a parameter to
SetRunning to indicate whether to reset the status, and pass false from
StopStream when stopping due to an error in OnOutputStopped.
- Around line 203-208: The code reads TrackIndex from config and stores it in
the local variable track (converting to 1-based), then uses it to look up the
correct bitrate key. However, when the audio encoder is actually created, the
mixer index is hardcoded to 0 instead of using the track value. Fix this by
passing track - 1 as the mixer_idx parameter to the audio encoder creation call
(converting from OBS's 1-based TrackIndex to libobs's 0-based mixer_idx). This
same issue appears in at least one other location as noted in the comment
(around line 240).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3a11cb86-bbdf-4a29-955c-1afc8355aed7

📥 Commits

Reviewing files that changed from the base of the PR and between 29a90c6 and 5f5c0e2.

📒 Files selected for processing (5)
  • CMakeLists.txt
  • CMakePresets.json
  • src/moq-dock.cpp
  • src/moq-dock.h
  • src/obs-moq.cpp

Comment thread src/moq-dock.cpp
Comment thread src/moq-dock.cpp
kixelated and others added 2 commits June 18, 2026 14:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Use the configured TrackIndex (1-based) as the libobs audio mixer index
  (0-based) instead of hardcoding mixer 0, so Advanced mode with Track 2+
  publishes the correct audio track.
- Set the stop failure message after StopStream() resets status to Idle, so
  the failure reason is actually shown.

Addresses CodeRabbit review feedback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kixelated kixelated merged commit 47bead8 into main Jun 18, 2026
3 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant