Skip to content

Commit bff5c45

Browse files
committed
test pass candidate process
1 parent 8c4d0af commit bff5c45

File tree

9 files changed

+166
-125
lines changed

9 files changed

+166
-125
lines changed

src/App.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function App() {
1717
const remoteVideoRef = useRef(null);
1818
// helper functions
1919
const saveSocket = useCallback(function saveSocket(s) {
20+
console.log('[App] save socket', s);
2021
socket.current = s;
2122
}, []);
2223
// const loadLocalVideo = useCallback(function loadLocalVideo(stream) {})

src/hooks/useMedia.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { useEffect, useState } from "react";
2+
import { setPeerConnection, setStream, peerConnection } from "../utils/media";
3+
import { useSelector } from "react-redux";
4+
5+
const configuration = {
6+
iceServers: [
7+
{
8+
urls: [
9+
"stun:stunserver.org",
10+
"stun:stun.voiparound.com",
11+
"stun:stun.voipbuster.com",
12+
"stun:stun.voipstunt.com",
13+
"stun:stun.voxgratia.org",
14+
],
15+
},
16+
],
17+
// sdpSemantics: "plan-b",
18+
};
19+
20+
function useMedia(videoRef, socket) {
21+
console.log("[useMedia] socket--", socket);
22+
const { role } = useSelector((state) => state.media);
23+
24+
useEffect(() => {
25+
const initPeerConnection = async () => {
26+
if (peerConnection == null) {
27+
console.log("create total new peer connection....");
28+
const stream = await navigator.mediaDevices.getUserMedia({
29+
video: true,
30+
// audio: true,
31+
});
32+
33+
// save local stream
34+
videoRef.current.srcObject = stream;
35+
setStream(stream);
36+
37+
// create peer connection
38+
const peerConnection = new RTCPeerConnection(configuration);
39+
// add tracks
40+
stream.getTracks().forEach((track) => {
41+
peerConnection.addTrack(track, stream);
42+
});
43+
44+
// save peer connection
45+
setPeerConnection(peerConnection);
46+
}
47+
48+
function onCandidate(event) {
49+
if (event.candidate) {
50+
console.log("iceCandidate", event.candidate);
51+
// emit candidate
52+
socket.current.emit(
53+
`candidate::${role == "" ? "initiator" : role}`,
54+
event.candidate
55+
);
56+
}
57+
}
58+
console.log("[useMedia] set onCandidate...");
59+
peerConnection.onicecandidate = onCandidate;
60+
// peerConnection.addEventListener("icecandidate", (event) => {
61+
// if (event.candidate) {
62+
// console.log("iceCandidate", event.candidate);
63+
// // emit candidate
64+
// socket.emit(
65+
// `candidate::${role == "" ? "initiator" : role}`,
66+
// event.candidate
67+
// );
68+
// }
69+
// });
70+
};
71+
initPeerConnection();
72+
}, [role, socket]);
73+
}
74+
75+
export default useMedia;

src/pages/Room/Layout.jsx

+10-11
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ import { useEffect, useRef, useState, useContext } from "react";
33
import { Modal } from "../../components/Modal";
44
import VideoWrapper from "./VideoWrapper";
55
import VideoActions from "./Actions";
6-
import { initSocket } from "../../utils/socket";
6+
import { initSocket, registerMoreEvents } from "../../utils/socket";
77
import { GlobalContext } from "../../App";
88
import ParticipantsList from "./ParticipantsList";
9-
// import { initWebRtc } from "../peer.tools";
10-
// import { useDispatch, useSelector } from "react-redux";
11-
// import { setPeerConnection } from "../../store/index";
9+
import { useDispatch, useSelector } from "react-redux";
1210

1311
export default function Room() {
12+
const dispatch = useDispatch();
1413
const { socket, saveSocket } = useContext(GlobalContext);
1514
const { roomId } = useParams();
1615
const dialogRef = useRef();
@@ -24,13 +23,13 @@ export default function Room() {
2423
if (username.value == "") {
2524
dialogRef.current.open();
2625
}
27-
saveSocket(initSocket("https://10.168.1.141:8000", { token: roomId }));
28-
29-
// async function prepare() {
30-
// const peerConnection = await initWebRtc();
31-
// dispatch(setPeerConnection(peerConnection));
32-
// }
33-
// prepare();
26+
const socket = initSocket(
27+
"https://10.168.1.141:8000",
28+
{ token: roomId },
29+
dispatch
30+
);
31+
registerMoreEvents(socket);
32+
saveSocket(socket);
3433
}, []);
3534

3635
function handleSetName() {

src/pages/Room/VideoWrapper.jsx

+8-33
Original file line numberDiff line numberDiff line change
@@ -22,45 +22,20 @@ import {
2222
ArrowDownTrayIcon,
2323
} from "@heroicons/react/24/solid";
2424
//
25-
import { useEffect, useRef, useState } from "react";
26-
import { initWebRtc } from "../peer.tools";
27-
import { useDispatch, useSelector } from "react-redux";
28-
import { handleStartNegotiation } from "../../utils/socket";
2925
import { useContext } from "react";
3026
import { GlobalContext } from "../../App";
27+
import useMedia from "../../hooks/useMedia";
3128

32-
export default function Room({}) {
29+
export default function VideoWrapper({}) {
3330
const { localVideoRef, remoteVideoRef, socket } = useContext(GlobalContext);
34-
const localStream = useRef();
35-
const remoteStream = useRef();
36-
37-
useEffect(() => {
38-
setTimeout(() => {
39-
console.log("localVideoRef", localVideoRef.current);
40-
console.log("remoteVideoRef", remoteVideoRef.current);
41-
}, 2000);
42-
async function prepare() {
43-
// peerConnection cannot be saved to redux store
44-
// dispatch(setPeerConnection(peerConnection)); is NOT allowed
45-
const peerConnection = await initWebRtc({
46-
ref: localVideoRef,
47-
stream: null,
48-
});
49-
console.log("socket", socket);
50-
// TODO:此处而言, negotiation::start 注册太晚了... 在 socket.js 中注册又太早
51-
socket.current.on("negotiation::start", () => {
52-
console.log("start negotiation");
53-
});
54-
55-
console.log("peerConnection -->", peerConnection);
56-
}
57-
prepare();
58-
}, []);
31+
// 初始化 peer connection
32+
console.log('[VideoWrapper] ', socket);
33+
useMedia(localVideoRef, socket);
5934

6035
function togglePlay() {
61-
selfVideoRef.current.paused
62-
? selfVideoRef.current.play()
63-
: selfVideoRef.current.pause();
36+
localVideoRef.current.paused
37+
? localVideoRef.current.play()
38+
: localVideoRef.current.pause();
6439
}
6540
return (
6641
<section className="main-area flex-1 flex justify-center items-center gap-10">

src/pages/peer.tools.js

+33-26
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
1-
function sendOfferToPeer(socket, offer) {
2-
console.log("Sending offer to peer");
3-
socket.emit("offer", { offer });
4-
}
5-
6-
function sendAnswerToPeer(socket, answer) {
7-
console.log("Sending answer to peer");
8-
socket.emit("answer", { answer });
9-
}
10-
11-
function sendIceCandidateToPeer(socket, iceCandidate) {
12-
console.log("Sending ICE candidate to peer");
13-
socket.emit("ice-candidate", { iceCandidate });
14-
}
15-
16-
function receiveOffer(socket, offer, peerConnection) {
17-
console.log("Receiving offer from peer");
18-
peerConnection.setRemoteDescription(offer);
19-
}
1+
import { setPeerConnection } from "../utils/media";
202

21-
function receiveAnswer(socket, answer, peerConnection) {
22-
console.log("Receiving answer from peer");
23-
peerConnection.setRemoteDescription(answer);
24-
}
25-
26-
export async function initWebRtc(selfVideo) {
3+
export async function initWebRtc(selfVideo, socket) {
4+
console.log("init webrtc ", selfVideo);
275
const stream = await navigator.mediaDevices.getUserMedia({
286
video: true,
297
// audio: true,
@@ -49,9 +27,38 @@ export async function initWebRtc(selfVideo) {
4927
peerConnection.addEventListener("icecandidate", (event) => {
5028
if (event.candidate) {
5129
console.log("iceCandidate", event.candidate);
30+
// inject
31+
socket.emit("candidate::initiator", event.candidate);
5232
}
5333
});
34+
setPeerConnection(peerConnection);
5435
// const offer = await peerConnection.createOffer();
5536
// peerConnection.setLocalDescription(offer);
56-
return peerConnection;
37+
38+
// return peerConnection;
5739
}
40+
41+
// function sendOfferToPeer(socket, offer) {
42+
// console.log("Sending offer to peer");
43+
// socket.emit("offer", { offer });
44+
// }
45+
46+
// function sendAnswerToPeer(socket, answer) {
47+
// console.log("Sending answer to peer");
48+
// socket.emit("answer", { answer });
49+
// }
50+
51+
// function sendIceCandidateToPeer(socket, iceCandidate) {
52+
// console.log("Sending ICE candidate to peer");
53+
// socket.emit("ice-candidate", { iceCandidate });
54+
// }
55+
56+
// function receiveOffer(socket, offer, peerConnection) {
57+
// console.log("Receiving offer from peer");
58+
// peerConnection.setRemoteDescription(offer);
59+
// }
60+
61+
// function receiveAnswer(socket, answer, peerConnection) {
62+
// console.log("Receiving answer from peer");
63+
// peerConnection.setRemoteDescription(answer);
64+
// }

src/pages/useMedia.js

-41
This file was deleted.

src/store/index.js

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { configureStore, createSlice } from "@reduxjs/toolkit";
2+
import { createOffer } from '../utils/media'
23

34
// media 相关 API
45
// getSenders()
56
// replaceTrack()
67
// getTracks()
78
// setSinkId() - change audio output
9+
// getCapabilities()
10+
// pc.addIceCandidate()
811

912
// Keywords:
1013
// Switching cameras in WebRTC
@@ -18,7 +21,8 @@ const mediaSlice = createSlice({
1821
videoDeviceId: "default", // 当前选中的视频设备id
1922
audioInputDeviceId: "default", // 当前选中的音频输入设备id
2023
audioOutputDeviceId: "default", // 当前选中的音频输出设备id
21-
24+
role: "", // 当前角色,用于区分 offer/answer
25+
offer: null,
2226
// 用于获取媒体流的约束条件,会随着选择而更新, replaceTrack()
2327
// 更换tracks的时候,是需要重新negotiation的, 也就是需要重新 createOffer
2428
constraints: {
@@ -56,6 +60,13 @@ const mediaSlice = createSlice({
5660
break;
5761
}
5862
},
63+
setRole(state, action) {
64+
state.role = action.payload;
65+
},
66+
setOffer(state, action) {
67+
state.offer = action.payload;
68+
state.role = 'initiator'; // <=== 这里设置角色
69+
},
5970
},
6071
});
6172

@@ -65,6 +76,13 @@ const store = configureStore({
6576
},
6677
});
6778

79+
export function setOfferCreator() {
80+
return async (dispatch) => {
81+
const offer = await createOffer();
82+
dispatch(mediaSlice.actions.setOffer(offer));
83+
};
84+
}
85+
6886
export default store;
69-
export const { setLocalStream, addRemoteStream, setDevice } =
87+
export const { setLocalStream, addRemoteStream, setDevice, setRole, setOffer } =
7088
mediaSlice.actions;

src/utils/media.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// variables - those variables cannot be put into redux
44
// let remoteStream = null;
5-
let peerConnection = null;
5+
export let peerConnection = null;
66
let localStream = null;
77
let remoteStreams = [];
88

@@ -33,5 +33,17 @@ export function setStream(source, stream) {
3333
}
3434

3535
export function setPeerConnection(pc) {
36+
console.log("setPeerConnection", pc);
3637
peerConnection = pc;
3738
}
39+
40+
export async function createOffer() {
41+
if (peerConnection) {
42+
const offer = await peerConnection.createOffer();
43+
peerConnection.setLocalDescription(offer);
44+
console.log("setLocalDescription", offer);
45+
return offer;
46+
}
47+
console.log("peerConnection is NULL");
48+
return null;
49+
}

0 commit comments

Comments
 (0)