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
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ npm run fix # Auto-fix code issues and audit dependencies

### Key Components

1. **MoQ Client Implementation** (`@kixelated/hang` package):
1. **MoQ Client Implementation** (`@moq/hang` package):
- Custom web components: `<hang-publish>`, `<hang-watch>`, `<hang-support>`
- WebTransport protocol for relay connections
- Publishing: `src/components/publish.tsx` - Creates broadcasts with random names
Expand Down Expand Up @@ -67,6 +67,6 @@ npm run fix # Auto-fix code issues and audit dependencies

- WebTransport requires HTTPS even in development (handled by vite-plugin-mkcert)
- Broadcasts are ephemeral - no persistence layer
- The `@kixelated/hang` package handles all MoQ protocol implementation
- The `@moq/hang` package handles all MoQ protocol implementation
- For new blog posts, add MDX files to `src/pages/blog/`
- Component changes in `src/components/` automatically reload with HMR
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<p align="center">
<img height="128px" src="https://github.com/kixelated/moq.dev/blob/main/public/home/logo.svg" alt="Media over QUIC">
<img height="128px" src="https://github.com/moq-dev/moq.dev/blob/main/public/home/logo.svg" alt="Media over QUIC">
</p>

This repository contains the code for [moq.dev](https://moq.dev).

This is a client only.
You'll either need to run a local server using [moq](https://github.com/kixelated/moq) or use a public server such as `cdn.moq.dev`.
You'll either need to run a local server using [moq](https://github.com/moq-dev/moq) or use a public server such as `cdn.moq.dev`.

Join the [Discord](https://discord.gg/FCYF3p99mr) for updates and discussion.

Expand Down
6 changes: 3 additions & 3 deletions astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export default defineConfig({
fs: {
allow: [
".",
// Allow `npm link @kixelated/hang`
fs.realpathSync(path.resolve("node_modules/@kixelated/hang")),
// Allow `npm link @moq/hang`
fs.realpathSync(path.resolve("node_modules/@moq/hang")),
],
},
},
Expand All @@ -37,7 +37,7 @@ export default defineConfig({
},
},
optimizeDeps: {
exclude: ["@kixelated/hang"],
exclude: ["@moq/hang"],
},
},
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"fix": "biome check --write && pnpm audit fix"
},
"dependencies": {
"@kixelated/hang": "^0.6.1",
"@moq/hang": "^0.1.0",
"astro": "^5.8.2",
"solid-js": "^1.9.7",
"unique-names-generator": "^4.7.1"
Expand Down
8 changes: 4 additions & 4 deletions src/components/publish.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { adjectives, animals, uniqueNamesGenerator } from "unique-names-generator";
import { createSignal } from "solid-js";

import "@kixelated/hang/support/element";
import "@kixelated/hang/publish/element";
import "@moq/hang/support/element";
import "@moq/hang/publish/element";

export default function () {
const name = uniqueNamesGenerator({ dictionaries: [adjectives, animals], separator: "-" });
Expand Down Expand Up @@ -71,7 +71,7 @@ export default function () {
<ul>
<li>
🔓 <strong>Open Source</strong>: <a href="/source">Typescript and Rust libraries</a>; this demo is{" "}
<a href="https://github.com/kixelated/moq/blob/main/js/hang-demo/src/publish.html">here</a>.
<a href="https://github.com/moq-dev/moq/blob/main/js/hang-demo/src/publish.html">here</a>.
</li>
<li>
🌐 <strong>100% Web</strong>: WebTransport, WebCodecs, WebAudio, WebWorkers, WebEtc.
Expand All @@ -95,7 +95,7 @@ export default function () {
</li>
<li>
🔧 <strong>Compatible</strong>: TCP fallback via{" "}
<a href="https://github.com/kixelated/web-transport/tree/main/web-transport-ws">WebSocket</a>, Safari fallback
<a href="https://github.com/moq-dev/web-transport/tree/main/web-transport-ws">WebSocket</a>, Safari fallback
via <a href="https://github.com/Yahweasel/libav.js/">libav.js.</a>
</li>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion src/components/support.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { onMount } from "solid-js";

export default function Support() {
onMount(() => {
import("@kixelated/hang/support/element");
import("@moq/hang/support/element");
});

return <hang-support prop:show="full" prop:details={true} />;
Expand Down
8 changes: 4 additions & 4 deletions src/components/watch.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Use the hang web components.
import "@kixelated/hang/support/element";
import "@kixelated/hang/watch/element";
import "@moq/hang/support/element";
import "@moq/hang/watch/element";
import { Show } from "solid-js";

export default function () {
Expand Down Expand Up @@ -39,7 +39,7 @@ export default function () {
<ul>
<li>
🔓 <strong>Open Source</strong>: <a href="/source">Typescript and Rust libraries</a>; this demo is{" "}
<a href="https://github.com/kixelated/moq/blob/main/js/hang-demo/src/index.html">here</a>.
<a href="https://github.com/moq-dev/moq/blob/main/js/hang-demo/src/index.html">here</a>.
</li>
<li>
🌐 <strong>100% Web</strong>: WebTransport, WebCodecs, WebAudio, WebWorkers, WebEtc.
Expand All @@ -65,7 +65,7 @@ export default function () {
</li>
<li>
🔧 <strong>Compatible</strong>: TCP fallback via{" "}
<a href="https://github.com/kixelated/web-transport/tree/main/web-transport-ws">WebSocket</a>, Safari fallback
<a href="https://github.com/moq-dev/web-transport/tree/main/web-transport-ws">WebSocket</a>, Safari fallback
via <a href="https://github.com/Yahweasel/libav.js/">libav.js.</a>
</li>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/blog/first-app.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ And maybe you can catch me in [hang.live/@moq](https://hang.live/@moq) when the
## Open Source
Even if you don't want to use a site designed for cringe teenagers, there's much to be excited about.

The core networking and media stuff is [open source](https://github.com/kixelated/moq), written in **Rust** and **Typescript**.
The core networking and media stuff is [open source](https://github.com/moq-dev/moq), written in **Rust** and **Typescript**.
I've been polishing the core libraries for a few years now, so they're actually pretty good.
There's some less-than-generic features, like [hang.live](https://hang.live) is using a track that contains the `x,y,z` coordinates of a broadcast.
However, *every* component is opt-in via `enabled: true` so you can pick your poison.
Expand Down
26 changes: 13 additions & 13 deletions src/pages/blog/first-cdn.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ Check it out if you want to see the ~cringe~ cool stuff you can do with MoQ.
This is a [technical preview](https://developers.cloudflare.com/moq/), so it's both free and subject to change.

Cloudflare is hosting a public `relay.cloudflare.mediaoverquic.com` endpoint that you can ~abuse~ test.
Connect using [my library](https://github.com/kixelated/moq), [Mike's fork](https://github.com/englishm/moq-rs), [Lorenzo's imquic](https://www.meetecho.com/blog/imquic/), [Meta's moxygen](https://github.com/facebookexperimental/moxygen), or any client that supports this limited subset of draft-07.
Connect using [my library](https://github.com/moq-dev/moq), [Mike's fork](https://github.com/englishm/moq-rs), [Lorenzo's imquic](https://www.meetecho.com/blog/imquic/), [Meta's moxygen](https://github.com/facebookexperimental/moxygen), or any client that supports this limited subset of draft-07.

I'm biased so naturally I'm going to use [@kixelated/hang](https://github.com/kixelated/moq/tree/main/js/hang) (smash that star button).
You can publish a live broadcast in the browser using the [web demo](/publish) or the [library](https://github.com/kixelated/moq/blob/main/js/hang-demo/src/publish.html#L25):
I'm biased so naturally I'm going to use [@moq/hang](https://github.com/moq-dev/moq/tree/main/js/hang) (smash that star button).
You can publish a live broadcast in the browser using the [web demo](/publish) or the [library](https://github.com/moq-dev/moq/blob/main/js/hang-demo/src/publish.html#L25):

```html
<script type="module">
// Registers the <hang-publish> element.
import "@kixelated/hang/publish/element";
import "@moq/hang/publish/element";
</script>

<!-- You'll need to replace `name` with something unique/random. -->
Expand All @@ -47,11 +47,11 @@ You can publish a live broadcast in the browser using the [web demo](/publish) o
</hang-publish>
```

There's a link to watch your live broadcast using the [web demo](/watch), or again you can use the [library](https://github.com/kixelated/moq/blob/9f5f6153458c03f255877a036e36f68f742d5c85/js/hang-demo/src/index.html#L30):
There's a link to watch your live broadcast using the [web demo](/watch), or again you can use the [library](https://github.com/moq-dev/moq/blob/9f5f6153458c03f255877a036e36f68f742d5c85/js/hang-demo/src/index.html#L30):
```html
<script type="module">
// Registers the <hang-watch> element.
import "@kixelated/hang/watch/element";
import "@moq/hang/watch/element";
</script>

<!-- Use the same name as the broadcast you published. -->
Expand All @@ -69,7 +69,7 @@ But that's a whole separate blog post; it's pretty cool.
[hang.live](/blog/first-app) uses the far more powerful Javascript API to do more complicated stuff like get access to individual video frames.
There's a *super secret* section at the end of this blog if you LOVE sample code, but I'm not going to bore the rest of you.

There's also a 🦀 Rust 🦀 library [to import MP4](https://github.com/kixelated/moq/tree/main/rs/hang), [pipe media from ffmpeg](https://github.com/kixelated/moq/blob/9f5f6153458c03f255877a036e36f68f742d5c85/rs/justfile#L103), and [publish/watch using gstreamer](https://github.com/kixelated/moq/blob/9f5f6153458c03f255877a036e36f68f742d5c85/rs/justfile#L119) so you can do more complicated media stuff without 🤮 Javascript 🤮.
There's also a 🦀 Rust 🦀 library [to import MP4](https://github.com/moq-dev/moq/tree/main/rs/hang), [pipe media from ffmpeg](https://github.com/moq-dev/moq/blob/9f5f6153458c03f255877a036e36f68f742d5c85/rs/justfile#L103), and [publish/watch using gstreamer](https://github.com/moq-dev/moq/blob/9f5f6153458c03f255877a036e36f68f742d5c85/rs/justfile#L119) so you can do more complicated media stuff without 🤮 Javascript 🤮.
I wish I could spend more time on the Rust side but **WebSupport** is a big deal.
We are no longer forced to use WebRTC, but that also means we need to build our own WebRTC in 🤮 Javascript 🤮.
I can suffer and you can reap the rewards.
Expand All @@ -82,15 +82,15 @@ Cloudflare is only supporting a *tiny* subset of an [old draft](https://www.ietf
They're using a [fork](https://github.com/englishm/moq-rs) of my terrible code so bugs are guaranteed.

- **There's no authentication yet**: choose an unguessable name for each broadcast.
- **There's no ANNOUNCE support**: my [conferencing example](https://github.com/kixelated/moq/blob/main/js/hang-demo/src/meet.html) uses **ANNOUNCE** to discover when broadcasts start/stop, so that won't work.
- **There's no ANNOUNCE support**: my [conferencing example](https://github.com/moq-dev/moq/blob/main/js/hang-demo/src/meet.html) uses **ANNOUNCE** to discover when broadcasts start/stop, so that won't work.
- **There's no [Safari support](https://caniuse.com/webtransport)**: [It's coming eventually](https://github.com/WebKit/standards-positions/issues/18#issuecomment-1495890122).
- **Nothing has been optimized**: the user experience will improve over time.

If any of these are deal breakers, then you could always run your own [moq-relay](https://github.com/kixelated/moq/tree/main/rs/moq-relay) in the meantime.
If any of these are deal breakers, then you could always run your own [moq-relay](https://github.com/moq-dev/moq/tree/main/rs/moq-relay) in the meantime.
I've been adding new features and fixing a bunch of stuff *after* Cloudflare smashed that fork button.
For example, authentication (via JWT) and a WebSocket fallback for Safari/TCP support.

There's even a [terraform module](https://github.com/kixelated/moq/blob/main/cdn/relay.tf) that powers `cdn.moq.dev`.
There's even a [terraform module](https://github.com/moq-dev/moq/blob/main/cdn/relay.tf) that powers `cdn.moq.dev`.
You too can run your own "global" CDN with 3 nodes and pay ~GCP~ Linode a boatload of money for the privilege.
It's not *quite* as good as Cloudflare's network, currently available for free...

Expand Down Expand Up @@ -168,10 +168,10 @@ I knew you would win.

Here's an example of my reactive library in action.
It powers [hang.live](/blog/first-app) so the API is subject to change and is probably already out of date.
When in doubt, [consult the source code](https://github.com/kixelated/moq/tree/main/js/hang) like the hacker you are.
When in doubt, [consult the source code](https://github.com/moq-dev/moq/tree/main/js/hang) like the hacker you are.

```typescript
import { Watch } from "@kixelated/hang"
import { Watch } from "@moq/hang"

// Start downloading a broadcast.
const watch = new Watch.Broadcast({
Expand All @@ -186,7 +186,7 @@ const watch = new Watch.Broadcast({
watch.audio.enabled.set(true);

// There are helpers to convert my custom signals, like for React:
import react from "@kixelated/signals/react"
import react from "@moq/signals/react"
const audioInfo = react(watch.audio.info); // a JSON blob of track information

// You could use the built-in renderers.
Expand Down
10 changes: 5 additions & 5 deletions src/pages/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,22 @@ There's a new way to achieve **real-time latency** in the browser, including con
- 🔓 **Open Source**: Production-ready [Rust and TypeScript libraries](/source).
- 🌐 **100% Web**: Utilizes [WebTransport](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport), [WebCodecs](https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API), [WebAudio](https://developer.mozilla.org/en-US/docs/Web/API/WebAudio_API), WebEtc.
- ⚡ **Real-time**: Minimal latency by skipping less important media during congestion.
- 🚀 **Massive Scale**: Host your own CDN with [moq-relay](https://github.com/kixelated/moq/tree/main/rs/moq-relay) or use [Cloudflare](/blog/first-cdn).
- 🎬 **Multi-Platform**: [Web](https://github.com/kixelated/moq/tree/main/js/hang), [FFmpeg](https://github.com/kixelated/moq/tree/main/rs/hang-cli), [GStreamer](https://github.com/kixelated/hang-gst), and [native](/source) clients available.
- 🚀 **Massive Scale**: Host your own CDN with [moq-relay](https://github.com/moq-dev/moq/tree/main/rs/moq-relay) or use [Cloudflare](/blog/first-cdn).
- 🎬 **Multi-Platform**: [Web](https://github.com/moq-dev/moq/tree/main/js/hang), [FFmpeg](https://github.com/moq-dev/moq/tree/main/rs/hang-cli), [GStreamer](https://github.com/moq-dev/gstreamer), and [native](/source) clients available.
- 🔍 **Discoverable**: Live notifications when broadcasts are published or finish.
- 💪 **Efficient**: No encoding or bandwidth usage until a viewer needs it.
- 🌍 **Compatible**: TCP fallback via [WebSocket](https://github.com/kixelated/web-transport/tree/main/web-transport-ws), Safari fallback via [libav.js](https://github.com/Yahweasel/libav.js/).
- 🌍 **Compatible**: TCP fallback via [WebSocket](https://github.com/moq-dev/web-transport/tree/main/web-transport-ws), Safari fallback via [libav.js](https://github.com/Yahweasel/libav.js/).
- 🔧 **Customizable**: Hardware accelerated encoding, the rest is in your control.

### *Standards
This website uses a [fork](/blog/transfork) of the IETF draft called [moq-lite](https://kixelated.github.io/moq-drafts/draft-lcurley-moq-lite.html) and a media layer called [hang](https://kixelated.github.io/moq-drafts/draft-lcurley-moq-hang.html).
This website uses a [fork](/blog/transfork) of the IETF draft called [moq-lite](https://moq-dev.github.io/moq-drafts/draft-lcurley-moq-lite.html) and a media layer called [hang](https://moq-dev.github.io/moq-drafts/draft-lcurley-moq-hang.html).
The principles behind MoQ are fantastic, but standards are **SLOW** and involve too much arguing.
My goal is to build something simple that you can use *now*, even if it's not a standard *yet*.


### Learn More
Check out the [blog](/blog) for more information and a smattering of jokes.
Once you're ready for more, check out the [Github](https://github.com/kixelated/moq) and/or join [Discord](https://discord.gg/FCYF3p99mr).
Once you're ready for more, check out the [Github](https://github.com/moq-dev/moq) and/or join [Discord](https://discord.gg/FCYF3p99mr).


Contributions are welcome, of course.
Expand Down
Loading
Loading