aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client-web/source/resource/mod.ts4
-rw-r--r--client-web/source/resource/track.ts17
-rw-r--r--client-web/source/track_handle.ts6
-rw-r--r--client-web/source/user/local.ts4
-rw-r--r--client-web/source/user/mod.ts2
-rw-r--r--client-web/source/user/remote.ts13
-rw-r--r--common/packets.d.ts2
-rw-r--r--readme.md1
8 files changed, 41 insertions, 8 deletions
diff --git a/client-web/source/resource/mod.ts b/client-web/source/resource/mod.ts
index d437260..3091a45 100644
--- a/client-web/source/resource/mod.ts
+++ b/client-web/source/resource/mod.ts
@@ -9,6 +9,8 @@ export type ChannelState = "running" | "disconnected"
export abstract class Resource {
el: HTMLElement = ediv({ class: ["channel"] })
+ on_destroy = () => { }
+
constructor(
public user: User,
public info: ProvideInfo,
@@ -23,6 +25,8 @@ export abstract class Resource {
this._state = value
}
+ destroy() { this.on_destroy() }
+
abstract create_element(): HTMLElement
abstract create_preview(): HTMLElement
diff --git a/client-web/source/resource/track.ts b/client-web/source/resource/track.ts
index ee87917..f58e020 100644
--- a/client-web/source/resource/track.ts
+++ b/client-web/source/resource/track.ts
@@ -1,12 +1,27 @@
import { ProvideInfo } from "../../../common/packets.d.ts";
import { ebutton } from "../helper.ts";
import { TrackHandle } from "../track_handle.ts";
+import { LocalUser } from "../user/local.ts";
import { User } from "../user/mod.ts";
import { Resource } from "./mod.ts";
export class TrackResource extends Resource {
- constructor(user: User, info: ProvideInfo, public track?: TrackHandle) {
+ private _track?: TrackHandle
+ constructor(user: User, info: ProvideInfo, track?: TrackHandle) {
super(user, info)
+ this.track = track
+ }
+
+ get track() { return this._track }
+ set track(value: TrackHandle | undefined) {
+ const handle_end = () => {
+ this.track = undefined
+ if (this.user instanceof LocalUser) this.destroy()
+ }
+ this._track?.removeEventListener("ended", handle_end)
+ this._track = value
+ this._track?.addEventListener("ended", handle_end)
+ this.update_el()
}
create_preview(): HTMLElement {
diff --git a/client-web/source/track_handle.ts b/client-web/source/track_handle.ts
index 98b2b2f..1bb9265 100644
--- a/client-web/source/track_handle.ts
+++ b/client-web/source/track_handle.ts
@@ -1,6 +1,8 @@
/// <reference lib="dom" />
export class TrackHandle extends EventTarget {
+ stream: MediaStream // this is used to create an id that is persistent across clients
+
constructor(
public track: MediaStreamTrack,
public local = false
@@ -15,12 +17,14 @@ export class TrackHandle extends EventTarget {
// drop all references to help gc
track.onunmute = track.onmute = track.onended = null
})
+
+ this.stream = new MediaStream([track])
}
get kind() { return this.track.kind }
get label() { return this.track.label }
get muted() { return this.track.muted }
- get id() { return this.track.id }
+ get id() { return this.stream.id } //!!
end() { this.track.stop(); this.dispatchEvent(new CustomEvent("ended")) }
}
diff --git a/client-web/source/user/local.ts b/client-web/source/user/local.ts
index 4b057ee..e5d22e5 100644
--- a/client-web/source/user/local.ts
+++ b/client-web/source/user/local.ts
@@ -72,6 +72,10 @@ export class LocalUser extends User {
this.el.append(r.el)
const provide: ProvideInfo = r.info
this.room.signaling.send_relay({ provide })
+ r.on_destroy = () => {
+ this.el.removeChild(r.el);
+ this.room.signaling.send_relay({ provide_stop: { id: r.info.id } })
+ }
}
send_track(t: TrackHandle) {
diff --git a/client-web/source/user/mod.ts b/client-web/source/user/mod.ts
index 59c58b7..85c6960 100644
--- a/client-web/source/user/mod.ts
+++ b/client-web/source/user/mod.ts
@@ -6,7 +6,7 @@ import { Resource } from "../resource/mod.ts";
import { Room } from "../room.ts"
export abstract class User {
- protected el: HTMLElement
+ public el: HTMLElement
public local = false
public resources: Map<string, Resource> = new Map()
diff --git a/client-web/source/user/remote.ts b/client-web/source/user/remote.ts
index 110fd40..59d811a 100644
--- a/client-web/source/user/remote.ts
+++ b/client-web/source/user/remote.ts
@@ -31,11 +31,15 @@ export class RemoteUser extends User {
this.update_stats()
}
this.peer.ontrack = ev => {
+ console.log(ev)
const t = ev.track
- log("media", `remote track: ${this.display_name}`, t)
- const r = this.resources.get(t.label)
- if (r instanceof TrackResource) { r.track = new TrackHandle(t); r.state = "running" }
+ const id = ev.streams[0].id
+ if (!id) return log({ scope: "media", warn: true }, "got a track without stream")
+ const r = this.resources.get(id)
+ if (!r) return log({ scope: "media", warn: true }, "got an unassociated track")
+ if (r instanceof TrackResource) r.track = new TrackHandle(t);
else log({ scope: "media", warn: true }, "got a track for a resource that should use data channel")
+ log("media", `remote track: ${this.display_name}`, t)
this.update_stats()
}
this.peer.onnegotiationneeded = () => {
@@ -73,6 +77,7 @@ export class RemoteUser extends User {
if (PREFS.notify_join) notify(`${this.display_name} joined`)
}
if (message.provide) {
+ console.log(message.provide.id);
const d = Resource.create(this, message.provide)
if (!d) return
this.el.append(d.el)
@@ -87,7 +92,7 @@ export class RemoteUser extends User {
if (!r) return log({ scope: "*", warn: true }, "somebody requested an unknown resource")
if (r instanceof TrackResource) {
if (!r.track) throw new Error("local resources not avail");
- const sender = this.peer.addTrack(r.track.track)
+ const sender = this.peer.addTrack(r.track.track, r.track.stream)
this.senders.set(r.track.id, sender)
r.track.addEventListener("end", () => { this.senders.delete(r.track?.id ?? "") })
}
diff --git a/common/packets.d.ts b/common/packets.d.ts
index 4ef4ad4..38059a3 100644
--- a/common/packets.d.ts
+++ b/common/packets.d.ts
@@ -35,7 +35,7 @@ export interface /* enum */ RelayMessage {
}
export interface ChatMessage { text?: string, image?: string }
export interface ProvideInfo {
- id: string,
+ id: string, // for datachannels this is `label`, for tracks this will be the `id` of the only associated stream.
kind: "audio" | "video" | "file"
label?: string
size?: number
diff --git a/readme.md b/readme.md
index 7a0e43b..06b90c4 100644
--- a/readme.md
+++ b/readme.md
@@ -115,6 +115,7 @@ keks-meet _tries_ to be secure. However I am not a security expert. The current
- How do we implement global hotkeys?
- Tray icon for native
- Pin js by bookmarking data:text/html loader page
+- Maybe group tracks in streams to make sure everything is in sync
## Protocol