Skip to main content

Broadcasting

info

This guide assumes you already finished either the Quick Setup or Installation guide.

You can also use Fishjam to broadcast your content to users.

In order to do this you need to create two flows.

  1. The first flow will be used to broadcast the content.
  2. The second flow will be used to receive the content.

Broadcasting

Configure permissions before broadcasting

Your app needs to have permissions configured in order to use the microphone and camera.

Android

Permissions below are required to stream audio and video with Fishjam on Android.

  • android.permission.CAMERA
  • android.permission.RECORD_AUDIO
  • android.permission.MODIFY_AUDIO_SETTINGS

Add required permissions to the app.json file.

app.json
{
"expo": {
...
"android": {
...
"permissions": [
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO",
"android.permission.MODIFY_AUDIO_SETTINGS"
]
}
}
}

iOS

You don't have to make any changes to run app on iOS. To update default content of permission alert, you can add these settings to app.json:

app.json
{
"expo": {
...
"ios": {
...
"infoPlist": {
"NSCameraUsageDescription": "Allow $(PRODUCT_NAME) to access your camera.",
"NSMicrophoneUsageDescription": "Allow $(PRODUCT_NAME) to access your microphone."
}
},
}
}

Here is an example of a very simple broadcaster that immediately broadcasts the front camera to all users in a room:

import { useEffect } from "react";
import {
useCamera,
useConnection,
VideoPreviewView,
} from "@fishjam-cloud/react-native-client";

export function Broadcaster() {
const { prepareCamera } = useCamera();
const { joinRoom, leaveRoom } = useConnection();

useEffect(() => {
const startBroadcasting = async () => {
console.log("Getting room details...");
const { url, peerToken } = await getRoomDetails(
"RoomName",
"BroadcastingUserName",
);

console.log("Preparing camera...");
await prepareCamera({ cameraEnabled: true });

await joinRoom({ url, peerToken });
console.log("Broadcasting...");
};

startBroadcasting();
return () => {
leaveRoom();
};
}, [prepareCamera, joinRoom, leaveRoom]);

return (
<VideoPreviewView
style={{ width: "90%", aspectRatio: 1, alignSelf: "center" }}
/>
);
}

async function getRoomDetails(roomName: string, peerName: string) {
// This will work ONLY for the Sandbox App
const response = await fetch(
`https://fishjam.io/api/v1/connect/${YOUR_APP_ID}/room-manager/?roomName=${roomName}&peerName=${peerName}`,
);
return response.json();
}

Receiving

Here is an example of a very simple receiver that receives the content from the broadcaster:

import { useEffect } from "react";
import { View } from "react-native";
import {
useConnection,
usePeers,
VideoRendererView,
} from "@fishjam-cloud/react-native-client";

export function Receiver() {
const { joinRoom, leaveRoom } = useConnection();
const { remotePeers } = usePeers();

const broadcastedTrack = remotePeers.at(0)?.cameraTrack;

useEffect(() => {
const startReceiving = async () => {
console.log("Getting room details...");
const { url, peerToken } = await getRoomDetails(
"RoomName",
"ReceivingUserName",
);
await joinRoom({ url, peerToken });
console.log("Receiving...");
};

startReceiving();

return () => {
leaveRoom();
};
}, [joinRoom, leaveRoom]);

if (!broadcastedTrack) {
return null;
}

return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<VideoRendererView
key={broadcastedTrack.id}
trackId={broadcastedTrack.id}
videoLayout="FIT"
style={{ width: "90%", aspectRatio: 1, backgroundColor: "black" }}
/>
</View>
);
}

async function getRoomDetails(roomName: string, peerName: string) {
// This will work ONLY for the Sandbox App
const response = await fetch(
`https://fishjam.io/api/v1/connect/${YOUR_APP_ID}/room-manager/?roomName=${roomName}&peerName=${peerName}`,
);
return response.json();
}