Skip to content

Commit 63edc24

Browse files
authored
FCE-1446 / receive broadcast with whep (#333)
## Description Implements `consumeBroadcast` function in `ts-client` and `useBroadcast` in `react-client`. For now, whep implementation is provided by `whep.js` package. ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
1 parent d6e1c86 commit 63edc24

File tree

23 files changed

+1936
-2705
lines changed

23 files changed

+1936
-2705
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": ["../../../.eslintrc.js"],
3+
"ignorePatterns": ["lib"],
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"printWidth": 80
3+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Fishjam Broadcast Example</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/src/main.tsx"></script>
11+
</body>
12+
</html>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "@fishjam-example/broadcast-example",
3+
"private": true,
4+
"version": "0.0.1",
5+
"type": "module",
6+
"license": "Apache-2.0",
7+
"scripts": {
8+
"dev": "vite",
9+
"build": "tsc && vite build",
10+
"watch": "tsc --noEmit --watch",
11+
"preview": "vite preview",
12+
"format": "prettier --write . --ignore-path ./.eslintignore",
13+
"format:check": "prettier --check . --ignore-path ./.eslintignore",
14+
"lint": "eslint . --ext .ts,.tsx --fix",
15+
"lint:check": "eslint . --ext .ts,.tsx"
16+
},
17+
"dependencies": {
18+
"@fishjam-cloud/react-client": "workspace:*",
19+
"react": "^19.0.0",
20+
"react-dom": "^19.0.0"
21+
},
22+
"devDependencies": {
23+
"@types/react": "^19.0.12",
24+
"@types/react-dom": "^19.0.4",
25+
"@vitejs/plugin-react-swc": "^3.8.1",
26+
"autoprefixer": "^10.4.21",
27+
"postcss": "^8.5.3",
28+
"typescript": "^5.8.2",
29+
"vite": "^6.2.5",
30+
"vite-plugin-checker": "^0.9.1"
31+
}
32+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { useLivestream } from "@fishjam-cloud/react-client";
2+
import { useState } from "react";
3+
4+
import VideoPlayer from "./VideoPlayer";
5+
6+
export const App = () => {
7+
const [token, setToken] = useState("");
8+
const [url, setUrl] = useState("");
9+
10+
const { connect, disconnect, stream } = useLivestream();
11+
12+
return (
13+
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
14+
<input
15+
value={url}
16+
onChange={(e) => setUrl(() => e?.target?.value)}
17+
placeholder="url"
18+
/>
19+
20+
<input
21+
value={token}
22+
onChange={(e) => setToken(() => e?.target?.value)}
23+
placeholder="token"
24+
/>
25+
26+
<div style={{ display: "flex", flexDirection: "row", gap: "8px" }}>
27+
<button
28+
disabled={token === "" || url === "" || !!stream}
29+
onClick={() => {
30+
if (token === "") throw Error("Token is empty");
31+
if (url === "") throw Error("Url is empty");
32+
connect(url, token);
33+
}}
34+
>
35+
Connect
36+
</button>
37+
38+
<button
39+
disabled={!stream}
40+
onClick={() => {
41+
disconnect();
42+
}}
43+
>
44+
Disconnect
45+
</button>
46+
</div>
47+
48+
{stream && <VideoPlayer stream={stream} />}
49+
</div>
50+
);
51+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useEffect, useRef } from "react";
2+
3+
type Props = {
4+
stream: MediaStream | null | undefined;
5+
};
6+
7+
const VideoPlayer = ({ stream }: Props) => {
8+
const videoRef = useRef<HTMLVideoElement>(null);
9+
10+
useEffect(() => {
11+
if (!videoRef.current) return;
12+
videoRef.current.srcObject = stream ?? null;
13+
}, [stream]);
14+
15+
return <video autoPlay playsInline muted ref={videoRef} />;
16+
};
17+
18+
export default VideoPlayer;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { FishjamProvider } from "@fishjam-cloud/react-client";
2+
import React from "react";
3+
import ReactDOM from "react-dom/client";
4+
5+
import { App } from "./components/App";
6+
7+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
8+
<React.StrictMode>
9+
<FishjamProvider>
10+
<App />
11+
</FishjamProvider>
12+
</React.StrictMode>,
13+
);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"module": "ESNext",
5+
"moduleResolution": "bundler"
6+
},
7+
"include": ["./src"]
8+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import react from "@vitejs/plugin-react-swc";
2+
import { defineConfig } from "vite";
3+
import checker from "vite-plugin-checker";
4+
5+
// https://vitejs.dev/config/
6+
export default defineConfig({
7+
server: {
8+
host: true,
9+
port: 3007,
10+
},
11+
plugins: [
12+
react(),
13+
checker({
14+
typescript: true,
15+
eslint: {
16+
lintCommand: "eslint --ext .ts,.tsx",
17+
},
18+
}),
19+
],
20+
});

0 commit comments

Comments
 (0)