Skip to content

Commit 119dca7

Browse files
committed
update next js project
1 parent 20fd94e commit 119dca7

File tree

5 files changed

+134
-80
lines changed

5 files changed

+134
-80
lines changed

demos/nextjs-demo/src/app/CanvasPage.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
'use client';
22

3+
import SmelterCanvasOutput from '@/app/components/SmelterCanvasOutput';
4+
import { useSmelter } from '@/app/hooks/useSmelter';
35
import { View, Text, useInputStreams, InputStream, Tiles } from '@swmansion/smelter';
4-
import Smelter, { setWasmBundleUrl } from '@swmansion/smelter-web-wasm';
6+
import { setWasmBundleUrl } from '@swmansion/smelter-web-wasm';
57
import { useCallback, useState } from 'react';
6-
import SmelterCanvas from './SmelterCanvas';
78

89
setWasmBundleUrl('/smelter.wasm');
910

1011
const CAMERA_ID = 'camera';
1112
const SCREEN_SHARE_ID = 'screen';
1213

1314
export default function CanvasPage() {
14-
const [smelter, setSmelter] = useState<Smelter>();
15+
const smelter = useSmelter();
1516
const [camera, setCamera] = useState<boolean>();
1617
const [screen, setScreen] = useState<boolean>();
1718

@@ -62,12 +63,15 @@ export default function CanvasPage() {
6263
<button onClick={toggleScreenShare} style={{ margin: 10 }}>
6364
Toggle screen capture
6465
</button>
65-
<p className="">Canvas: </p>
66+
<p>Canvas: </p>
6667
</div>
6768
<div>
68-
<SmelterCanvas width={1280} height={720} onSmelterCreated={setSmelter}>
69-
<SmelterComponent />
70-
</SmelterCanvas>
69+
{
70+
smelter &&
71+
<SmelterCanvasOutput smelter={smelter} width={1280} height={720} audio>
72+
<SmelterComponent />
73+
</SmelterCanvasOutput>
74+
}
7175
</div>
7276
</div>
7377
);

demos/nextjs-demo/src/app/SmelterCanvas.tsx

Lines changed: 0 additions & 71 deletions
This file was deleted.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React, { useCallback, useEffect, useRef, useState } from 'react';
2+
import type Smelter from '@swmansion/smelter-web-wasm';
3+
4+
type CanvasProps = React.DetailedHTMLProps<
5+
React.CanvasHTMLAttributes<HTMLCanvasElement>,
6+
HTMLCanvasElement
7+
>;
8+
9+
type SmelterCanvasProps = {
10+
smelter: Smelter;
11+
audio?: boolean;
12+
children: React.ReactElement;
13+
} & CanvasProps;
14+
15+
type UpdatedProps = {
16+
smelter: Smelter;
17+
width?: number | string;
18+
height?: number | string;
19+
audio?: boolean;
20+
};
21+
22+
type RegisterOptions = UpdatedProps & {
23+
outputId: string;
24+
canvas: HTMLCanvasElement;
25+
};
26+
27+
const getNewOutputId = (() => {
28+
let counter = 1;
29+
return () => {
30+
const outputId = `output-${counter}`;
31+
counter += 1;
32+
return outputId;
33+
};
34+
})();
35+
36+
export default function SmelterCanvasOutput(props: SmelterCanvasProps) {
37+
const { children, smelter, audio, ...canvasProps } = props;
38+
const [updatedProps, setUpdatedProps] = useState<UpdatedProps | undefined>();
39+
const [registerOptions, setRegisterOptions] = useState<RegisterOptions | undefined>(undefined);
40+
const key = useRef<number>(1);
41+
42+
const canvasRef = useCallback(
43+
async (updatedCanvas: HTMLCanvasElement | null) => {
44+
if (!updatedCanvas || !updatedProps || updatedCanvas === registerOptions?.canvas) {
45+
return;
46+
}
47+
const outputId = getNewOutputId();
48+
setRegisterOptions({
49+
...updatedProps,
50+
outputId,
51+
canvas: updatedCanvas,
52+
});
53+
},
54+
[updatedProps, registerOptions]
55+
);
56+
57+
useEffect(() => {
58+
// force new canvas
59+
key.current += 1;
60+
61+
setUpdatedProps({
62+
smelter,
63+
width: canvasProps.width,
64+
height: canvasProps.height,
65+
audio,
66+
});
67+
}, [canvasProps.width, canvasProps.height, smelter, audio]);
68+
69+
useEffect(() => {
70+
if (!registerOptions) {
71+
return;
72+
}
73+
const { audio, outputId, width, height, canvas } = registerOptions;
74+
const promise = smelter.registerOutput(outputId, children, {
75+
type: 'canvas',
76+
video: {
77+
canvas,
78+
resolution: {
79+
width: Number(width ?? canvas?.width),
80+
height: Number(height ?? canvas?.height),
81+
},
82+
},
83+
audio,
84+
});
85+
86+
return () => {
87+
void promise
88+
.catch(console.error)
89+
.then(() => smelter.unregisterOutput(outputId))
90+
.catch(console.error);
91+
};
92+
}, [registerOptions]);
93+
94+
return <canvas key={key.current} ref={canvasRef} {...canvasProps} />;
95+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Smelter from '@swmansion/smelter-web-wasm';
2+
import { useEffect, useState } from 'react';
3+
4+
export function useSmelter(): Smelter | undefined {
5+
const [smelter, setSmelter] = useState<Smelter>();
6+
useEffect(() => {
7+
const smelter = new Smelter();
8+
9+
let cancel = false;
10+
const promise = (async () => {
11+
await smelter.init();
12+
await smelter.start();
13+
if (!cancel) {
14+
setSmelter(smelter);
15+
}
16+
})();
17+
18+
return () => {
19+
cancel = true;
20+
void (async () => {
21+
await promise.catch(() => {});
22+
await smelter.terminate();
23+
})();
24+
};
25+
}, []);
26+
return smelter;
27+
}

demos/vite-demo/src/pages/CanvasPage.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { View, Text, useInputStreams, InputStream, Tiles } from '@swmansion/smelter';
2-
import Smelter, { setWasmBundleUrl } from '@swmansion/smelter-web-wasm';
2+
import { setWasmBundleUrl } from '@swmansion/smelter-web-wasm';
33
import { useCallback, useState } from 'react';
4-
import SmelterCanvas from '../components/SmelterCanvasOutput';
54
import { useSmelter } from '../hooks/useSmelter';
65
import SmelterCanvasOutput from '../components/SmelterCanvasOutput';
76

0 commit comments

Comments
 (0)