Skip to content

Commit

Permalink
Use the namespace instead of URL. (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
kixelated authored Mar 20, 2024
1 parent 31623d4 commit a52e448
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 21 deletions.
3 changes: 2 additions & 1 deletion lib/contribute/broadcast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Catalog, Mp4Track, VideoTrack, Track as CatalogTrack, AudioTrack } from
import { isAudioTrackSettings, isVideoTrackSettings } from "../common/settings"

export interface BroadcastConfig {
namespace: string
connection: Connection
media: MediaStream

Expand All @@ -31,7 +32,7 @@ export class Broadcast {
constructor(config: BroadcastConfig) {
this.connection = config.connection
this.config = config
this.catalog = new Catalog()
this.catalog = new Catalog(config.namespace)

for (const media of this.config.media.getTracks()) {
const track = new Track(media, config)
Expand Down
21 changes: 11 additions & 10 deletions lib/media/catalog/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,35 @@ import { asError } from "../../common/error"

// JSON encoded catalog
export class Catalog {
namespace: string
tracks = new Array<Track>()

constructor(namespace: string) {
this.namespace = namespace
}

encode(): Uint8Array {
const encoder = new TextEncoder()
const str = JSON.stringify(this)
return encoder.encode(str)
}

static decode(raw: Uint8Array): Catalog {
decode(raw: Uint8Array) {
const decoder = new TextDecoder()
const str = decoder.decode(raw)

try {
const catalog = new Catalog()
catalog.tracks = JSON.parse(str).tracks

if (!isCatalog(catalog)) {
this.tracks = JSON.parse(str).tracks
if (!isCatalog(this)) {
throw new Error("invalid catalog")
}

return catalog
} catch (e) {
throw new Error("invalid catalog")
}
}

static async fetch(connection: Connection): Promise<Catalog> {
const subscribe = await connection.subscribe("", ".catalog")
async fetch(connection: Connection) {
const subscribe = await connection.subscribe(this.namespace, ".catalog")
try {
const segment = await subscribe.data()
if (!segment) throw new Error("no catalog data")
Expand All @@ -41,7 +42,7 @@ export class Catalog {
await segment.close()
await subscribe.close() // we done

return Catalog.decode(chunk.payload)
this.decode(chunk.payload)
} catch (e) {
const err = asError(e)

Expand Down
8 changes: 5 additions & 3 deletions lib/playback/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type Timeline = Message.Timeline

export interface PlayerConfig {
url: string
namespace: string
fingerprint?: string // URL to fetch TLS certificate fingerprint
element: HTMLCanvasElement | HTMLVideoElement
}
Expand Down Expand Up @@ -53,7 +54,8 @@ export class Player {
const client = new Client({ url: config.url, fingerprint: config.fingerprint, role: "subscriber" })
const connection = await client.connect()

const catalog = await Catalog.fetch(connection)
const catalog = new Catalog(config.namespace)
await catalog.fetch(connection)

let backend

Expand Down Expand Up @@ -94,7 +96,7 @@ export class Player {
}

async #runInit(name: string) {
const sub = await this.#connection.subscribe("", name)
const sub = await this.#connection.subscribe(this.#catalog.namespace, name)
try {
const init = await Promise.race([sub.data(), this.#running])
if (!init) throw new Error("no init data")
Expand All @@ -114,7 +116,7 @@ export class Player {
throw new Error(`unknown track kind: ${track.kind}`)
}

const sub = await this.#connection.subscribe("", track.data_track)
const sub = await this.#connection.subscribe(this.#catalog.namespace, track.data_track)
try {
for (;;) {
const segment = await Promise.race([sub.data(), this.#running])
Expand Down
7 changes: 4 additions & 3 deletions web/src/components/publish.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ export default function Publish() {
return tracks[0].getSettings() as VideoTrackSettings
})

const id = crypto.randomUUID()
let watchUrl = `/watch/${id}`
const name = crypto.randomUUID()
let watchUrl = `/watch/${name}`
if (server != import.meta.env.PUBLIC_RELAY_HOST) {
watchUrl = `${watchUrl}?server=${server}`
}

createEffect(() => {
const url = `https://${server}/${id}`
const url = `https://${server}`

// Special case localhost to fetch the TLS fingerprint from the server.
// TODO remove this when WebTransport correctly supports self-signed certificates
Expand Down Expand Up @@ -145,6 +145,7 @@ export default function Publish() {
media: d,
audio: a,
video: v,
namespace: name,
})
}

Expand Down
5 changes: 3 additions & 2 deletions web/src/components/watch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ export default function Watch(props: { name: string }) {

const [usePlayer, setPlayer] = createSignal<Player | undefined>()
createEffect(() => {
const url = `https://${server}/${props.name}`
const namespace = props.name
const url = `https://${server}`

// Special case localhost to fetch the TLS fingerprint from the server.
// TODO remove this when WebTransport correctly supports self-signed certificates
const fingerprint = server.startsWith("localhost") ? `https://${server}/fingerprint` : undefined

const element = useElement()
Player.create({ url, fingerprint, element }).then(setPlayer).catch(setError)
Player.create({ url, fingerprint, element, namespace }).then(setPlayer).catch(setError)
})

createEffect(() => {
Expand Down
2 changes: 0 additions & 2 deletions web/src/pages/watch/[name].astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ if (!name) return Astro.redirect("/404")
import Issues from "@/components/issues.astro"
import Watch from "@/components/watch.tsx"
import Clock from "@/components/clock.tsx"
import Layout from "@/layouts/global.astro"
---

Expand All @@ -16,6 +15,5 @@ import Layout from "@/layouts/global.astro"
<p>
Watching a <strong>PUBLIC</strong> broadcast. Pls report any abuse.
</p>
{name == "bbb" && <Clock client:only />}
<Watch name={name} client:only />
</Layout>

0 comments on commit a52e448

Please sign in to comment.