Skip to content
This repository was archived by the owner on Feb 10, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions examples/video-player/App.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,63 @@
import { StyleSheet, View } from 'react-native';
import FishjamPlayer from './components/FishjamPlayer';

const roomName = 'test';
import { StyleSheet, TextInput, View, Button } from 'react-native';
import FishjamPlayerViewer from './components/FishjamPlayerViewer';
import FishjamPlayerStreamer from './components/FishjamPlayerStreamer';
import { useState } from 'react';

const App = () => {
const [roomName, setRoomName] = useState('test-room');
const [selection, setSelection] = useState<'streamer' | 'viewer' | 'none'>(
'none',
);

return (
<View style={styles.videoContainer}>
<FishjamPlayer roomName={roomName} />
<View style={styles.container}>
{selection === 'none' && (
<>
<TextInput
style={styles.textInput}
placeholder="Room Name"
value={roomName}
onChangeText={setRoomName}
/>
<Button title="Stream" onPress={() => setSelection('streamer')} />
<Button title="View stream" onPress={() => setSelection('viewer')} />
</>
)}
{selection === 'streamer' && (
<>
<FishjamPlayerStreamer roomName={roomName} />
<Button title="Back" onPress={() => setSelection('none')} />
</>
)}
{selection === 'viewer' && (
<>
<FishjamPlayerViewer roomName={roomName} />
<Button title="Back" onPress={() => setSelection('none')} />
</>
)}
</View>
);
};

export default App;

const styles = StyleSheet.create({
videoContainer: {
container: {
flex: 1,
position: 'relative',
justifyContent: 'center',
alignItems: 'center',
padding: 16,
backgroundColor: 'black',
},
textInput: {
width: '100%',
height: 40,
borderWidth: 1,
borderColor: 'gray',
borderRadius: 8,
padding: 8,
color: 'white',
backgroundColor: 'black',
marginBottom: 16,
},
});
16 changes: 14 additions & 2 deletions examples/video-player/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,27 @@
"ios": {
"supportsTablet": true,
"bundleIdentifier": "io.fishjam.example.videoplayer",
"requireFullScreen": true
"requireFullScreen": true,
"infoPlist": {
"NSAppTransportSecurity": {
"NSAllowsArbitraryLoads": true
},
"NSCameraUsageDescription": "We need to access your camera for video calls.",
"NSMicrophoneUsageDescription": "We need to access your microphone so you can talk during calls."
},
"appleTeamId": "J5FM626PE2"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"edgeToEdgeEnabled": true,
"package": "io.fishjam.example.videoplayer"
"package": "io.fishjam.example.videoplayer",
"permissions": [
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO"
]
},
"web": {
"favicon": "./assets/favicon.png"
Expand Down
108 changes: 0 additions & 108 deletions examples/video-player/components/FishjamPlayer.tsx

This file was deleted.

62 changes: 62 additions & 0 deletions examples/video-player/components/FishjamPlayerStreamer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { useCallback, useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import {
LivestreamStreamer,
useLivestreamStreamer,
cameras,
VideoParameters,
} from '@fishjam-cloud/react-native-client/livestream';
import { useSandbox } from '@fishjam-cloud/react-native-client';

interface FishjamPlayerStreamerProps {
roomName: string;
}

const FishjamPlayerStreamer = ({ roomName }: FishjamPlayerStreamerProps) => {
const { getSandboxLivestream } = useSandbox({
fishjamId: process.env.EXPO_PUBLIC_FISHJAM_ID,
});

const { connect, disconnect, whipClientRef } = useLivestreamStreamer({
videoEnabled: true,
audioEnabled: true,
camera: cameras[0],
videoParameters: VideoParameters.presetHD169,
});

const handleConnect = useCallback(async () => {
try {
const { streamerToken } = await getSandboxLivestream(roomName, false);
await connect(streamerToken);
} catch (err) {
console.error(err);
}
}, [connect, getSandboxLivestream, roomName]);

useEffect(() => {
handleConnect();

return () => {
disconnect();
};
}, [handleConnect, disconnect]);

return (
<View style={styles.playerContentContainer}>
<LivestreamStreamer
style={{ height: '90%', aspectRatio: 16 / 9 }}
ref={whipClientRef}
/>
</View>
);
};

const styles = StyleSheet.create({
playerContentContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

export default FishjamPlayerStreamer;
63 changes: 63 additions & 0 deletions examples/video-player/components/FishjamPlayerViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useCallback, useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import {
LivestreamViewer,
useLivestreamViewer,
} from '@fishjam-cloud/react-native-client/livestream';
import { useSandbox } from '@fishjam-cloud/react-native-client';

interface FishjamPlayerViewerProps {
roomName: string;
pictureInPicture?: boolean;
}

const FishjamPlayerViewer = ({
roomName,
pictureInPicture = true,
}: FishjamPlayerViewerProps) => {
const { getSandboxViewerToken } = useSandbox({
fishjamId: process.env.EXPO_PUBLIC_FISHJAM_ID,
});

const { connect, disconnect, whepClientRef } = useLivestreamViewer();

const handleConnect = useCallback(async () => {
try {
const token = await getSandboxViewerToken(roomName);
await connect({ token });
} catch (err) {
console.error(err);
}
}, [connect, getSandboxViewerToken, roomName]);

useEffect(() => {
handleConnect();

return () => {
disconnect();
};
}, [handleConnect, disconnect]);

return (
<View style={styles.playerContentContainer}>
<LivestreamViewer
style={{ height: '90%', aspectRatio: 16 / 9 }}
pipEnabled={pictureInPicture}
autoStartPip={pictureInPicture}
autoStopPip={pictureInPicture}
pipSize={{ width: 1920, height: 1080 }}
ref={whepClientRef}
/>
</View>
);
};

const styles = StyleSheet.create({
playerContentContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

export default FishjamPlayerViewer;
Loading