trying to get stream stuff working

This commit is contained in:
talksik
2022-05-14 12:28:53 -05:00
parent 9a1207a939
commit 0f972dba53
2 changed files with 79 additions and 5 deletions
@@ -19,7 +19,7 @@
* listen for any calls to me, as well as any answers back to me
*/
import React, { useEffect } from 'react';
import React, { useEffect, useContext, useState, useRef } from 'react';
import Peer from 'simple-peer';
import useRealTimeRooms from './RealTimeRoomProvider';
import useAuth from './AuthProvider';
@@ -34,6 +34,7 @@ import {
} from '@nirvana/core/sockets/channels';
import { ServerResponseChannels } from '../../../core/sockets/channels';
import toast from 'react-hot-toast';
import { usePrevious } from 'react-use';
type PeerMap = {
[userId: string]: Peer;
@@ -54,6 +55,9 @@ export function StreamProvider({ children }: { children: React.ReactChild }) {
const [peerMap, updatePeerMap] = useImmer<PeerMap>({});
const [userLocalStream, setUserLocalStream] = useState<MediaStream>();
const localStreamRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
$ws.on(
ServerResponseChannels.RTC_RECEIVING_ANSWER_RESPONSE,
@@ -79,6 +83,7 @@ export function StreamProvider({ children }: { children: React.ReactChild }) {
const peerForMeAndNewbie = new Peer({
initiator: false,
stream: userLocalStream ?? null,
trickle: false, // prevents the multiple tries on different ice servers and signal from getting called a bunch of times
});
@@ -131,6 +136,7 @@ export function StreamProvider({ children }: { children: React.ReactChild }) {
const localPeerConnection = new Peer({
initiator: true,
stream: userLocalStream ?? null,
trickle: false, // prevents the multiple tries on different ice servers and signal from getting called a bunch of times
});
@@ -146,9 +152,38 @@ export function StreamProvider({ children }: { children: React.ReactChild }) {
});
}, [user, roomsMap, $ws, updatePeerMap]); //TODO: make this not run on EVERY update to roomsMap? only tuned in lists? so the separate map for that?
const prevStream = usePrevious<MediaStream>(userLocalStream);
useEffect(() => {
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((localMediaStream: MediaStream) => {
setUserLocalStream(localMediaStream);
if (localStreamRef.current) localStreamRef.current.srcObject = localMediaStream;
});
}, [localStreamRef]);
useEffect(() => {
if (prevStream) {
Object.values(peerMap).forEach((currentPeer) => {
currentPeer.removeStream(prevStream);
currentPeer.addStream(userLocalStream);
});
}
}, [userLocalStream, peerMap, prevStream]);
console.log(peerMap);
return (
<StreamProviderContext.Provider value={{ peerMap }}>{children}</StreamProviderContext.Provider>
<StreamProviderContext.Provider value={{ peerMap }}>
<video height={400} width={400} autoPlay muted ref={localStreamRef} />
{children}
</StreamProviderContext.Provider>
);
}
export default function useStreams() {
return useContext(StreamProviderContext);
}
@@ -1,4 +1,4 @@
import React, { useMemo } from 'react';
import React, { useMemo, useEffect, useRef } from 'react';
import useAuth from '../../../../providers/AuthProvider';
import useRealTimeRooms from '../../../../providers/RealTimeRoomProvider';
@@ -6,6 +6,8 @@ import { LineMemberState } from '@nirvana/core/models/line.model';
import LineIcon from '../../../../components/lineIcon';
import { FiActivity, FiHeadphones, FiSettings, FiSun } from 'react-icons/fi';
import { Avatar, Tooltip } from 'antd';
import useStreams from '../../../../providers/StreamProvider';
import Peer from 'simple-peer';
export default function MainPanel() {
const { user } = useAuth();
@@ -39,13 +41,13 @@ function LineDetails() {
const selectedLine = useMemo(() => roomsMap[selectedLineId], [selectedLineId, roomsMap]);
console.log('selected line', selectedLine);
const isUserToggleTuned = useMemo(
() => selectedLine?.currentUserMember?.state === LineMemberState.TUNED,
[selectedLine],
);
const { peerMap } = useStreams();
// seeing if I am in the list of broadcasters
// the source of truth from the socket connections telling me if my clicking actually made a round trip
const isUserBroadcasting = useMemo(
@@ -276,6 +278,9 @@ function LineDetails() {
</div>
))}
</div>
{/* change to show only the broadcasters */}
<LineStreams broadcasters={selectedLine.tunedInMemberIds} />
</div>
<button
@@ -289,3 +294,37 @@ function LineDetails() {
</div>
);
}
function LineStreams({ broadcasters }: { broadcasters: string[] }) {
const { peerMap } = useStreams();
return (
<div className="flex flex-col">
{broadcasters.map((userId) => {
const currentPeer = peerMap[userId];
return <Stream key={`streamDisplay-${userId}`} peer={currentPeer} />;
})}
</div>
);
}
function Stream({ peer }: { peer: Peer }) {
const streamRef = useRef<HTMLAudioElement>(null);
useEffect(() => {
peer.on('stream', (remotePeerStream: MediaStream) => {
console.log(
'stream coming in from remote peer...BUT, only going to show once they broadcast',
);
const audio = new Audio();
audio.autoplay = true;
audio.srcObject = remotePeerStream;
if (streamRef?.current) streamRef.current.srcObject = remotePeerStream;
});
}, []);
return <>this is a stream component of one remote peer</>;
}