@historydev
Острая аллергия на анимешников

Почему эффект не получает current из ref?

Здравствуйте. Мне нужно получить localMediaStream в одном эффекте, при том что устанавливается он в другом эффекте. Скажите пожалуйста, почему в данном контексте он всегда null (если не устанавливать его в этом-же эффекте), однако в таком случае у меня дублируется userMedia. Последствия - камера не гаснет когда я коллю track.stop(). За основу был взят этот пакет.

const peerConnections = useRef({});
	const localMediaStream = useRef(null);
	const peerMediaElements = useRef({
		[LOCAL_VIDEO]: null,
	});

	useEffect(() => {
		async function handleNewPeer({peerID, createOffer}) {
			if (peerID in peerConnections.current) {
				return console.warn(`Already connected to peer ${peerID}`);
			}

			peerConnections.current[peerID] = new RTCPeerConnection({
				iceServers: freeice(),
			});

			peerConnections.current[peerID].onicecandidate = event => {
				if (event.candidate) {
					socket.emit(ACTIONS.RELAY_ICE, {
						peerID,
						iceCandidate: event.candidate,
					});
				}
			}

			let tracksNumber = 0;
			peerConnections.current[peerID].ontrack = ({streams: [remoteStream]}) => {
				tracksNumber++

				if (tracksNumber === 2) { // video & audio tracks received
					tracksNumber = 0;
					addNewClient(peerID, () => {
						if (peerMediaElements.current[peerID]) {
							peerMediaElements.current[peerID].srcObject = remoteStream;
						} else {
							// FIX LONG RENDER IN CASE OF MANY CLIENTS
							let settled = false;
							const interval = setInterval(() => {
								if (peerMediaElements.current[peerID]) {
									peerMediaElements.current[peerID].srcObject = remoteStream;
									settled = true;
								}

								if (settled) {
									clearInterval(interval);
								}
							}, 1000);
						}
					});
				}
			}

			/*localMediaStream.current = await navigator.mediaDevices.getUserMedia({
				audio: audio,
				video: video
			})*/

			localMediaStream.current.getTracks().forEach(track => { // localMediaStream null
				peerConnections.current[peerID].addTrack(track, localMediaStream.current);
			});

			if (createOffer) {
				const offer = await peerConnections.current[peerID].createOffer();

				await peerConnections.current[peerID].setLocalDescription(offer);

				socket.emit(ACTIONS.RELAY_SDP, {
					peerID,
					sessionDescription: offer,
				});
			}
		}

		socket.on(ACTIONS.ADD_PEER, handleNewPeer);

		return () => {
			socket.off(ACTIONS.ADD_PEER);
		}
	}, []);

// Установка, всё как в исходнике, оно и не работало пока я не добавил костыль выше, однако когда дошло до остановки видео-потока, появился баг с вечно включённой камерой

useEffect(() => {

		async function startCapture() {
			console.log('start capture');

			localMediaStream.current = await navigator.mediaDevices.getUserMedia({
				audio: audio,
				video: video
			}).catch(console.log);


			addNewClient(LOCAL_VIDEO, () => {
				const localVideoElement = peerMediaElements.current[LOCAL_VIDEO];

				if (localVideoElement) {
					localVideoElement.volume = 0;
					localVideoElement.srcObject = localMediaStream.current;
				}
			});

		}

		startCapture().then((data) => socket.emit(ACTIONS.JOIN, {room: roomID})).catch((e) => console.error(e)).finally(() => console.log('finally'));

		console.log(roomID);

		return () => {
			localMediaStream.current.getTracks().forEach(track => track.stop());
			socket.emit(ACTIONS.LEAVE);
		};

	}, [roomID]);


Спасибо большое!
  • Вопрос задан
  • 55 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы