Custom sources
If you only wish to send camera, microphone or screen share output through Fishjam, then you most likely should refer to the documentation in Streaming media and Managing devices instead of this page.
This section demonstrates how to stream non-standard video or audio to other peers in your web app. The utilities in this section allow you to integrate Fishjam with powerful browser APIs such as WebGL and WebGPU, or higher level libraries, which leverage these APIs, such as Three.js, Smelter or PixiJS
Creating a custom source - useCustomSource()
To create a custom source, you only need to do two things:
- Call the
useCustomSource
hook. - Call the
setStream
callback provided by theuseCustomSource
hook with a MediaStream object.
Usage Example
import { useCustomSource } from "@fishjam-cloud/react-client";
export function CameraControl() {
const stream: MediaStream = ...
const { setStream } = useCustomSource("my-custom-source");
useEffect(() => {
setStream(stream);
}, [stream, setStream]);
...
}
Using a created custom source
Once you have called setStream
for a given source ID (in the above example, "my-custom-source"
), any subsequent calls to useCustomSource
with the same ID will return the same state.
This enables multiple components to control and read a shared custom source.
Deleting a custom source
If you wish to remove a custom source, then you should call the setStream
callback with null
as its argument.
Usage Example
const { setStream } = useCustomSource("my-custom-source");
...
await setStream(null);
How to get a MediaStream object?
Depending on your use-case, the way you can obtain a MediaStream will vary. Below are some common examples of how to obtain one from an existing video or audio source.
Canvas
If you have a <canvas>
HTML element, then you will need to call the captureStream
method of the given canvas.
This is particularly useful if you are using Three.js or PixiJS to render complex animations and more.
Usage Example
import { useCallback, useState } from "react";
export function CanvasExample() {
const [canvasStream, setCanvasStream] = useState<MediaStream>();
const streamFromCanvas = useCallback((canvas: HTMLCanvasElement | null) => {
if (!canvas) return;
setCanvasStream(canvas.captureStream());
}, []);
// use canvasStream as desired
return <canvas ref={streamFromCanvas} />;
}
Smelter
If you are using Smelter, then all you need to do is register an output via registerOutput
.
Usage Example
If you want to see a full example React app which uses Fishjam with Smelter, then you can check out our full example on GitHub.
const { stream } = await smelter.registerOutput("example-output", <View />, {
type: "stream",
video: {
resolution: { width: 1920, height: 1080 },
},
});
Video/Audio HTML tag
If you have a <video>
or <audio>
element, then you need to call their captureStream
method, analogously as you would with a canvas
.
Usage Example
- Video
- Audio
import { useCallback, useState } from "react";
export function CanvasExample() {
const [stream, setStream] = useState<MediaStream>();
const streamFromVideo = useCallback((video: HTMLVideoElement | null) => {
if (!video) return;
setStream(video.captureStream());
}, []);
// use stream as desired
return <video ref={streamFromVideo} ... />;
}
import { useCallback, useState } from "react";
export function CanvasExample() {
const [stream, setStream] = useState<MediaStream>();
const streamFromAudio = useCallback((audio: HTMLAudioElement | null) => {
if (!audio) return;
setStream(audio.captureStream());
}, []);
// use stream as desired
return <audio ref={streamFromAudio} ... />;
}