Skip to content

Commit f567583

Browse files
committed
add video and context wc
1 parent 215423e commit f567583

File tree

7 files changed

+111
-32
lines changed

7 files changed

+111
-32
lines changed

client-web/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
</head>
1111

1212
<body>
13-
<video></video>
13+
<pulsebeam-context>
14+
</pulsebeam-context>
1415
</body>
1516

1617
</html>

client-web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"preview": "vite preview"
2626
},
2727
"dependencies": {
28+
"@lit/context": "^1.1.5",
2829
"@protobuf-ts/runtime": "^2.10.0",
2930
"lit": "^3.3.0",
3031
"nanostores": "^1.0.1"

client-web/src/component.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { html, LitElement } from "lit";
2+
import { customElement, property, query } from "lit/decorators.js";
3+
import { consume, createContext, provide } from "@lit/context";
4+
import { ClientCore } from "./lib";
5+
import type { ParticipantMeta } from "./lib/core";
6+
7+
const clientContext = createContext<ClientCore>(Symbol("client"));
8+
9+
@customElement("pulsebeam-context")
10+
export class PulsebeamContext extends LitElement {
11+
@provide({ context: clientContext })
12+
@property({ attribute: false })
13+
value!: ClientCore;
14+
15+
@query("slot")
16+
slotEl!: HTMLSlotElement;
17+
18+
private audioElements: HTMLAudioElement[] = [];
19+
20+
firstUpdated() {
21+
this.audioElements = Array.from(this.renderRoot.querySelectorAll("audio"));
22+
console.log("Audio elements:", this.audioElements);
23+
}
24+
25+
render() {
26+
return html`
27+
<audio></audio>
28+
<audio></audio>
29+
<audio></audio>
30+
31+
<slot></slot>
32+
`;
33+
}
34+
}
35+
36+
@customElement("pulsebeam-video")
37+
export class PulsebeamVideo extends LitElement {
38+
@property({ attribute: false })
39+
participantMeta?: ParticipantMeta;
40+
41+
@consume({ context: clientContext, subscribe: true })
42+
client?: ClientCore;
43+
44+
@query("video")
45+
videoEl!: HTMLVideoElement;
46+
47+
firstUpdated() {
48+
if (!this.client) {
49+
console.warn("No client context available");
50+
return;
51+
}
52+
53+
if (!this.participantMeta) {
54+
console.warn("No participant specified on <pulsebeam-video>");
55+
return;
56+
}
57+
58+
this.client.subscribeVideo(this.videoEl, this.participantMeta);
59+
}
60+
61+
render() {
62+
return html`<video autoplay muted playsinline></video>`;
63+
}
64+
}
65+
66+
declare global {
67+
interface HTMLElementTagNameMap {
68+
"pulsebeam-context": PulsebeamContext;
69+
"pulsebeam-video": PulsebeamVideo;
70+
}
71+
}

client-web/src/index.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
1+
import type { PulsebeamVideo } from "./component";
12
import { ClientCore } from "./lib";
3+
export * from "./component";
4+
5+
const context = document.querySelector("pulsebeam-context");
26

37
(async () => {
48
const client = new ClientCore({
59
sfuUrl: "http://localhost:3000/",
610
maxDownstreams: 1,
711
});
12+
context!.value = client;
813

9-
const videos: Record<string, HTMLVideoElement> = {};
14+
const videos: Record<string, PulsebeamVideo> = {};
1015
client.$state.listen((v) => console.log(v));
11-
client.$participants.listen((newValue, _, changed) => {
12-
const video = videos[changed] || document.createElement("video");
13-
const participant = newValue[changed].get();
14-
client.subscribe(video, participant);
16+
client.$participants.listen(async (newValue, _, changed) => {
17+
// Create a new pulsebeam-video element if not already present
18+
let video = videos[changed];
19+
if (video) {
20+
return;
21+
}
22+
23+
video = document.createElement("pulsebeam-video") as PulsebeamVideo;
1524
videos[changed] = video;
25+
await video.updateComplete;
26+
27+
// Set participantMeta on the pulsebeam-video element
28+
const participantMeta = newValue[changed].get(); // Get the metadata for the participant
29+
video.participantMeta = participantMeta;
30+
console.log(participantMeta);
31+
32+
// Append the video to the DOM
33+
context!.appendChild(video);
1634
});
1735
await client.connect("default", `alice-${Math.round(Math.random() * 100)}`);
1836

client-web/src/lib/core.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,11 @@ export class ClientCore {
339339
}
340340

341341
// TODO: remove browser specific
342-
subscribe(video: HTMLVideoElement, participant: ParticipantMeta) {
342+
subscribeVideo(video: HTMLVideoElement, participant: ParticipantMeta) {
343343
video.srcObject = participant.stream;
344344
video.autoplay = true;
345345
}
346+
347+
subscribeAudio(audio: HTMLAudioElement) {
348+
}
346349
}

client-web/src/pulsebeam-connector.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)