Skip to content

@moq/publish

npmTypeScript

Publish media to MoQ broadcasts. Provides both a JavaScript API and a <moq-publish> Web Component, plus an optional <moq-publish-ui> overlay.

Installation

bash
bun add @moq/publish
# or
npm add @moq/publish

No-build CDN usage

For quick demos or single-page embeds where a bundler is overkill, load the package straight from esm.sh. esm.sh serves the package as a browser-ready ESM module and rewrites bare imports (like @moq/hang, @moq/net) to other esm.sh URLs, so it loads in the browser with no import map or local build step:

html
<script type="module">
    import "https://esm.sh/@moq/publish/element";
    import "https://esm.sh/@moq/publish/ui";
</script>

<moq-publish-ui>
    <moq-publish url="https://relay.example.com/anon" name="room/alice.hang" source="camera">
        <video muted autoplay></video>
    </moq-publish>
</moq-publish-ui>

Pin a version range in the URL for production, e.g. https://esm.sh/@moq/publish@0.2/element. jsDelivr's +esm endpoint (https://cdn.jsdelivr.net/npm/@moq/publish/element.js/+esm) works the same way if you prefer it.

For anything beyond embedding on a static page, install the package and use a real bundler (the examples below).

Web Component

html
<script type="module">
    import "@moq/publish/element";
</script>

<moq-publish
    url="https://relay.example.com/anon"
    name="room/alice.hang"
    audio video controls>
    <video muted autoplay></video>
</moq-publish>

Attributes:

  • url (required) — Relay server URL
  • name (required) — Broadcast name
  • source — Input to capture: "camera", "screen", or "file"
  • muted — Mute audio capture (boolean)
  • invisible — Disable video capture (boolean)
  • preview — What the preview renders: "source" (default), "encoded", or "none" to disable it (see Preview element)
  • announce — When to publish the broadcast: "true" (default, announce as soon as the element connects), "false" (never announce), or "source" (hold off until a source is selected). The JS property takes a real boolean or "source" (el.announce = false)

Preview element

<moq-publish> discovers a nested <video> or <canvas> and uses it for a local preview.

  • <video> attaches the raw capture stream via srcObject. This is the cheapest preview and the default.
  • <canvas> draws the frames itself. With preview="source" (default) it draws the raw capture; with preview="encoded" it draws a decoded copy of the encoded video, so the preview shows exactly what a viewer receives over the network, codec artifacts and all.

The encoded mode costs a full extra encode + decode pass (it re-encodes with the same settings as the published rendition), so reach for it when you want to monitor the transmitted quality, not as the default preview. Set preview="none" to disable the preview without removing the element.

html
<moq-publish url="https://relay.example.com/anon" name="room/alice.hang" source="camera" preview="encoded">
    <canvas></canvas>
</moq-publish>

UI Overlay

Import @moq/publish/ui for a Web Component overlay with device selection and publishing controls:

html
<script type="module">
    import "@moq/publish/element";
    import "@moq/publish/ui";
</script>

<moq-publish-ui>
    <moq-publish
        url="https://relay.example.com/anon"
        name="room/alice.hang"
        audio video>
        <video muted autoplay></video>
    </moq-publish>
</moq-publish-ui>

The <moq-publish-ui> element automatically discovers the nested <moq-publish> and wires up reactive controls.

JavaScript API

typescript
import * as Publish from "@moq/publish";

const broadcast = new Publish.Broadcast({
    connection,
    enabled: true,
    name: "alice.hang",
    video: { enabled: true, device: "camera" },
    audio: { enabled: true },
});

// Reactive controls
broadcast.video.device.set("screen");
broadcast.name.set("bob.hang");
  • @moq/watch — Subscribe to and render MoQ broadcasts
  • @moq/hang — Core media library (catalog, container, support)
  • @moq/net — Core pub/sub transport protocol

Licensed under MIT or Apache-2.0