From 49cd0f87bd8821a3003623880042d0e1f8ab22a4 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Tue, 9 Dec 2025 22:47:39 +1100 Subject: [PATCH] Rename to the new org. --- CLAUDE.md | 4 ++-- README.md | 4 ++-- astro.config.ts | 6 +++--- package.json | 2 +- src/components/publish.tsx | 8 ++++---- src/components/support.tsx | 2 +- src/components/watch.tsx | 8 ++++---- src/pages/blog/first-app.mdx | 2 +- src/pages/blog/first-cdn.mdx | 26 +++++++++++++------------- src/pages/index.mdx | 10 +++++----- src/pages/source.mdx | 28 ++++++++++++++-------------- 11 files changed, 50 insertions(+), 50 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index c024ad5..5d57ecc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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: ``, ``, `` - WebTransport protocol for relay connections - Publishing: `src/components/publish.tsx` - Creates broadcasts with random names @@ -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 diff --git a/README.md b/README.md index d67cb5e..207d329 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@

- Media over QUIC + Media over QUIC

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. diff --git a/astro.config.ts b/astro.config.ts index 0e7f9a5..dd72a98 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -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")), ], }, }, @@ -37,7 +37,7 @@ export default defineConfig({ }, }, optimizeDeps: { - exclude: ["@kixelated/hang"], + exclude: ["@moq/hang"], }, }, }); diff --git a/package.json b/package.json index b08753e..b743838 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/src/components/publish.tsx b/src/components/publish.tsx index dc6644b..bf9e97d 100644 --- a/src/components/publish.tsx +++ b/src/components/publish.tsx @@ -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: "-" }); @@ -71,7 +71,7 @@ export default function () { diff --git a/src/components/support.tsx b/src/components/support.tsx index f8995db..edecd9c 100644 --- a/src/components/support.tsx +++ b/src/components/support.tsx @@ -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 ; diff --git a/src/components/watch.tsx b/src/components/watch.tsx index b4dd76d..d1974c2 100644 --- a/src/components/watch.tsx +++ b/src/components/watch.tsx @@ -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 () { @@ -39,7 +39,7 @@ export default function () { diff --git a/src/pages/blog/first-app.mdx b/src/pages/blog/first-app.mdx index 9d46a11..74fcd5a 100644 --- a/src/pages/blog/first-app.mdx +++ b/src/pages/blog/first-app.mdx @@ -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. diff --git a/src/pages/blog/first-cdn.mdx b/src/pages/blog/first-cdn.mdx index 28e9bd0..3f0af5c 100644 --- a/src/pages/blog/first-cdn.mdx +++ b/src/pages/blog/first-cdn.mdx @@ -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 @@ -47,11 +47,11 @@ You can publish a live broadcast in the browser using the [web demo](/publish) o
``` -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 @@ -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. @@ -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... @@ -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({ @@ -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. diff --git a/src/pages/index.mdx b/src/pages/index.mdx index 4ac1fad..303afb5 100644 --- a/src/pages/index.mdx +++ b/src/pages/index.mdx @@ -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. diff --git a/src/pages/source.mdx b/src/pages/source.mdx index bbb70a0..bd56f7c 100644 --- a/src/pages/source.mdx +++ b/src/pages/source.mdx @@ -7,45 +7,45 @@ title: Source Everything is open source and broken into two repositories: -- [kixelated/moq](https://github.com/kixelated/moq): The core MoQ library, with implementations in Rust and Typescript. -- [kixelated/moq.dev](https://github.com/kixelated/moq.dev): This website. Includes terraform to run multiple relays on GCP. +- [moq-dev/moq](https://github.com/moq-dev/moq): The core MoQ library, with implementations in Rust and Typescript. +- [moq-dev/moq.dev](https://github.com/moq-dev/moq.dev): This website. Includes terraform to run multiple relays on GCP. ## Rust -Native code is written in [Rust](https://github.com/kixelated/moq/tree/main/rs) and is split into a few notable crates: +Native code is written in [Rust](https://github.com/moq-dev/moq/tree/main/rs) and is split into a few notable crates: | crate | description | | ----------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | [moq-lite](https://docs.rs/moq-lite/latest/moq_lite/) | A generic pub/sub transport. This is a minimal reinterpretation of the IETF [MoqTransport draft](https://datatracker.ietf.org/doc/draft-ietf-moq-transport/). | -| [moq-relay](https://github.com/kixelated/moq/tree/main/rs/moq-relay) | A Moq server that connects publishers to subscribers, caching and deduplicating any subscriptions. Note that MoQ does not support P2P; instead it utilizes relays to scale out to many subscribers. | -| [moq-clock](https://github.com/kixelated/moq/tree/main/rs/moq-clock) | It's a clock! Just to demonstrate that MoQ can be used for more than media. | +| [moq-relay](https://github.com/moq-dev/moq/tree/main/rs/moq-relay) | A Moq server that connects publishers to subscribers, caching and deduplicating any subscriptions. Note that MoQ does not support P2P; instead it utilizes relays to scale out to many subscribers. | +| [moq-clock](https://github.com/moq-dev/moq/tree/main/rs/moq-clock) | It's a clock! Just to demonstrate that MoQ can be used for more than media. | | [hang](https://docs.rs/hang/latest/hang/) | A media specific library built on top of moq-lite. This provides a JSON "catalog" that describes the media tracks and "container" that literally consists of a timestamp. The actual media decoding/encoding is left to the platform. | -| [hang-cli](https://github.com/kixelated/moq/tree/main/hang-cli) | A client that integrates with ffmpeg to publish media. This pipes fMP4 over stdin, so it's not the most efficient... | -| [hang-gst](https://github.com/kixelated/hang-gst) | A GStreamer plugin for publishing and consuming media. Separate repository to avoid GStreamer build dependency. | -| [hang-wasm](https://github.com/kixelated/moq/tree/main/hang-wasm) | An MoQ web client utilizing WebAssembly, WebCodecs, and WebTransport. Deprecated in favor of the Typescript implementation; see below for justification. | +| [hang-cli](https://github.com/moq-dev/moq/tree/main/hang-cli) | A client that integrates with ffmpeg to publish media. This pipes fMP4 over stdin, so it's not the most efficient... | +| [hang-gst](https://github.com/moq-dev/gstreamer) | A GStreamer plugin for publishing and consuming media. Separate repository to avoid GStreamer build dependency. | +| [hang-wasm](https://github.com/moq-dev/moq/tree/main/hang-wasm) | An MoQ web client utilizing WebAssembly, WebCodecs, and WebTransport. Deprecated in favor of the Typescript implementation; see below for justification. | There are some additional crates in other repositories that might be of interest: | crate | description | | ----: | ----------- | | [web-transport-quinn](https://docs.rs/web-transport-quinn/latest/web_transport_quinn/) | A [WebTransport](https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/) client and server utilizing [Quinn](https://github.com/quinn-rs/quinn). Copies the Quinn API and abstracts away the HTTP/3 handshake. | -| [web-transport-wasm](https://github.com/kixelated/web-transport-rs/tree/main/web-transport-wasm) | A WASM [WebTransport](https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/) wrapper around the `web-sys` bindings. | -| [web-transport](https://github.com/kixelated/web-transport-rs) | A common (opinionated) interface, utilizing one of the above depending on the platform. This is what the `moq-lite` crate uses. | +| [web-transport-wasm](https://github.com/moq-dev/web-transport/tree/main/web-transport-wasm) | A WASM [WebTransport](https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/) wrapper around the `web-sys` bindings. | +| [web-transport](https://github.com/moq-dev/web-transport) | A common (opinionated) interface, utilizing one of the above depending on the platform. This is what the `moq-lite` crate uses. | | [web-codecs](https://docs.rs/web-codecs/latest/web_codecs/) | A wrapper around the [WebCodecs API](https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API) for WASM. | | [web-streams](https://docs.rs/web-streams/latest/web_streams/) | A wrapper around the [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) for WASM. | ## Typescript -Web code is written in [Typescript](https://github.com/kixelated/moq/tree/main/js) and is split into a few packages: +Web code is written in [Typescript](https://github.com/moq-dev/moq/tree/main/js) and is split into a few packages: | package | description | | ------- | ----------- | -| [@kixelated/moq](https://www.npmjs.com/package/@kixelated/moq) | A moq-lite client that mirrors the Rust API. You can publish and subscribe to generic tracks. Any media stuff is implemented at a higher layer. | -| [@kixelated/hang](https://www.npmjs.com/package/@kixelated/hang) | A media library. This is where the bulk of the cool stuff happens, like capturing/encoding or decoding/rendering media. Includes Web Components to make setup super simple. [See the demos](https://github.com/kixelated/moq/tree/main/js/hang/demo). | +| [@moq/moq](https://www.npmjs.com/package/@moq/moq) | A moq-lite client that mirrors the Rust API. You can publish and subscribe to generic tracks. Any media stuff is implemented at a higher layer. | +| [@moq/hang](https://www.npmjs.com/package/@moq/hang) | A media library. This is where the bulk of the cool stuff happens, like capturing/encoding or decoding/rendering media. Includes Web Components to make setup super simple. [See the demos](https://github.com/moq-dev/moq/tree/main/js/hang/demo). | **Note**: These utilize browser-specific APIs and there's no currently no support for Node and other server runtimes. [Deno](https://deno.com/) is doing some cool stuff with WebTransport so maybe it'll work there someday. -And before you ask, yes, it is possible to use WASM for web support as demonstrated by the [hang-wasm](https://github.com/kixelated/moq/tree/main/hang-wasm) crate. +And before you ask, yes, it is possible to use WASM for web support as demonstrated by the [hang-wasm](https://github.com/moq-dev/moq/tree/main/hang-wasm) crate. However, it involves a lot of boilerplate, wrappers, and casting. The performance is not great because the WASM sandbox doesn't have networking or device access, requiring copying and/or message passing to use Web APIs.