const socketUrl = "https://webrtc.theuy.nl";
const signalingChannel = createIoSignalingChannel(socketUrl, {
autoConnect: true
});
root.render(
<StrictMode>
<SignalingChannelProvider signalingChannel={signalingChannel}>
<App />
</SignalingChannelProvider>
</StrictMode>
);
import createIoSignalingChannel, {
SignalingChannelProvider
} from "webrtc-react-socketio/signaling";
Step 1: Create signaling channel
Import our package
Initialize the signaling channel
Provide the signaling channel to our app
export default function App() {
// use signaling channel
const { isConnected, join, broadcast } = useSignalingChannel();
const [room, setRoom] = useState<string>();
// change the room when we get a room id from the server
const onResponseCallback: OnResponseCallback = useCallback((response) => {
setRoom(response.room.id);
}, []);
// create room callback
const createRoom = useCallback((isBroadcast = true) => {
const payload = { onResponseCallback };
isBroadcast ? broadcast(payload) : join(payload);
}, [broadcast, join, onResponseCallback]);
// show create broadcast button or render our Room
return !isConnected ? (
<span>loading...</span>
) : !room ? (
<button onClick={() => createRoom()}>Create Broadcast</button>
) : (
<AudioRoom room={room} />
);
}
Step 2: Handle room creation
Now we can use our signaling channel in our react components
const [isRecording, setIsRecording] = useState(false);
const audioRef = useRef<HTMLAudioElement>(null);
const streamRef = useRef<MediaStream>();
Step 3: Create our room component
Add some state and refs to facilitate the audio tracks
const { addTrack, removeTrack } = usePeerConnection({
room,
onTrack: (track) => {
if (audioRef.current) {
audioRef.current.srcObject = track.streams[0];
}
track.streams[0].onremovetrack = () => {
if (audioRef.current) {
audioRef.current.srcObject = null;
}
};
}
});
Initialize peer connection and listen for audio tracks
const toggleBroadcast = useCallback(async () => {
if (!streamRef.current) {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: false
});
stream.getTracks().forEach((track) => addTrack(track, stream));
streamRef.current = stream;
setIsRecording(true);
} else {
streamRef.current.getTracks().forEach((track) => track.stop());
streamRef.current = undefined;
removeTrack();
setIsRecording(false);
}
}, [addTrack, removeTrack]);
Step 3: Create our room component
Toggle broadcast callback
return (<div>
<audio ref={audioRef} autoPlay />
<button onClick={() => toggleBroadcast()}>
{isRecording ? "Stop" : "Start"} recording
</button>
</div>);
Render audio element and recording toggle button
import { useCallback, useEffect } from "react";
import { usePeerConnection } from "webrtc-react-socketio";
import { useSignalingChannel } from "webrtc-react-socketio/signaling";
export default function TextRoom({ room }: { room: string }) {
const { socket } = useSignalingChannel();
const { createDataChannel, sendMessage } = usePeerConnection({
room,
onMessage: (data) => console.log("new message", data)
});
const onNewMember = useCallback(
({ room, from: remotePeerId }: { room: string; from: string }) => {
createDataChannel({ room, remotePeerId });
},
[createDataChannel]
);
useEffect(() => {
socket.on("new member", onNewMember);
return () => {
socket.off("new member", onNewMember);
};
}, [socket, onNewMember]);
return <button onClick={() => sendMessage({ message: "randomstring" })}>
Send
</button>;
}
BONUS: Room example with data channels