@voicemaster/core 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +60 -58
- package/dist/index.mjs +60 -48
- package/package.json +1 -1
- package/src/VoiceClient.ts +64 -54
package/dist/index.d.mts
CHANGED
|
@@ -7,7 +7,7 @@ interface VoiceClientConfig {
|
|
|
7
7
|
}
|
|
8
8
|
declare class VoiceClient {
|
|
9
9
|
private ws;
|
|
10
|
-
private
|
|
10
|
+
private pc;
|
|
11
11
|
private localStream;
|
|
12
12
|
private remoteStream;
|
|
13
13
|
private eventHandlers;
|
|
@@ -21,10 +21,13 @@ declare class VoiceClient {
|
|
|
21
21
|
private emit;
|
|
22
22
|
connect(): Promise<void>;
|
|
23
23
|
private initMicrophone;
|
|
24
|
+
private initPeerConnection;
|
|
24
25
|
private initWebSocket;
|
|
25
26
|
private handleSignalingMessage;
|
|
26
|
-
private
|
|
27
|
-
private
|
|
27
|
+
private createOffer;
|
|
28
|
+
private handleOffer;
|
|
29
|
+
private handleAnswer;
|
|
30
|
+
private handleCandidate;
|
|
28
31
|
private send;
|
|
29
32
|
disconnect(): void;
|
|
30
33
|
toggleMute(): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ interface VoiceClientConfig {
|
|
|
7
7
|
}
|
|
8
8
|
declare class VoiceClient {
|
|
9
9
|
private ws;
|
|
10
|
-
private
|
|
10
|
+
private pc;
|
|
11
11
|
private localStream;
|
|
12
12
|
private remoteStream;
|
|
13
13
|
private eventHandlers;
|
|
@@ -21,10 +21,13 @@ declare class VoiceClient {
|
|
|
21
21
|
private emit;
|
|
22
22
|
connect(): Promise<void>;
|
|
23
23
|
private initMicrophone;
|
|
24
|
+
private initPeerConnection;
|
|
24
25
|
private initWebSocket;
|
|
25
26
|
private handleSignalingMessage;
|
|
26
|
-
private
|
|
27
|
-
private
|
|
27
|
+
private createOffer;
|
|
28
|
+
private handleOffer;
|
|
29
|
+
private handleAnswer;
|
|
30
|
+
private handleCandidate;
|
|
28
31
|
private send;
|
|
29
32
|
disconnect(): void;
|
|
30
33
|
toggleMute(): void;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -35,11 +25,10 @@ __export(index_exports, {
|
|
|
35
25
|
module.exports = __toCommonJS(index_exports);
|
|
36
26
|
|
|
37
27
|
// src/VoiceClient.ts
|
|
38
|
-
var import_simple_peer = __toESM(require("simple-peer"));
|
|
39
28
|
var VoiceClient = class {
|
|
40
29
|
constructor(config) {
|
|
41
30
|
this.ws = null;
|
|
42
|
-
this.
|
|
31
|
+
this.pc = null;
|
|
43
32
|
this.localStream = null;
|
|
44
33
|
this.remoteStream = null;
|
|
45
34
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -69,6 +58,7 @@ var VoiceClient = class {
|
|
|
69
58
|
async connect() {
|
|
70
59
|
try {
|
|
71
60
|
await this.initMicrophone();
|
|
61
|
+
this.initPeerConnection();
|
|
72
62
|
this.initWebSocket();
|
|
73
63
|
} catch (error) {
|
|
74
64
|
this.emit("error", error);
|
|
@@ -84,75 +74,89 @@ var VoiceClient = class {
|
|
|
84
74
|
});
|
|
85
75
|
this.emit("localStream", this.localStream);
|
|
86
76
|
}
|
|
77
|
+
initPeerConnection() {
|
|
78
|
+
this.pc = new RTCPeerConnection({ iceServers: this.iceServers });
|
|
79
|
+
this.localStream?.getTracks().forEach((track) => {
|
|
80
|
+
this.pc.addTrack(track, this.localStream);
|
|
81
|
+
});
|
|
82
|
+
this.pc.ontrack = (event) => {
|
|
83
|
+
this.remoteStream = event.streams[0];
|
|
84
|
+
this.emit("remoteStream", this.remoteStream);
|
|
85
|
+
if (!this.isConnectedFlag) {
|
|
86
|
+
this.isConnectedFlag = true;
|
|
87
|
+
this.emit("connected");
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
this.pc.onicecandidate = (event) => {
|
|
91
|
+
if (event.candidate) {
|
|
92
|
+
this.send({
|
|
93
|
+
type: "candidate",
|
|
94
|
+
candidate: event.candidate
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
87
99
|
initWebSocket() {
|
|
88
100
|
const url = `${this.signalingUrl}?userId=${this.userId}&roomId=${this.roomId}`;
|
|
89
101
|
this.ws = new WebSocket(url);
|
|
90
102
|
this.ws.onopen = () => {
|
|
91
103
|
this.send({ type: "join", roomId: this.roomId, userId: this.userId });
|
|
92
104
|
};
|
|
93
|
-
this.ws.onmessage = (event) => {
|
|
105
|
+
this.ws.onmessage = async (event) => {
|
|
94
106
|
const message = JSON.parse(event.data);
|
|
95
|
-
this.handleSignalingMessage(message);
|
|
107
|
+
await this.handleSignalingMessage(message);
|
|
96
108
|
};
|
|
97
109
|
this.ws.onclose = () => {
|
|
98
110
|
this.emit("disconnected");
|
|
99
111
|
};
|
|
100
112
|
}
|
|
101
|
-
handleSignalingMessage(message) {
|
|
113
|
+
async handleSignalingMessage(message) {
|
|
102
114
|
switch (message.type) {
|
|
103
115
|
case "user-joined":
|
|
104
116
|
if (message.userId !== this.userId) {
|
|
105
|
-
this.
|
|
117
|
+
await this.createOffer();
|
|
106
118
|
this.emit("userJoined", message.userId);
|
|
107
119
|
}
|
|
108
120
|
break;
|
|
109
|
-
case "
|
|
110
|
-
this.
|
|
121
|
+
case "offer":
|
|
122
|
+
await this.handleOffer(message);
|
|
123
|
+
break;
|
|
124
|
+
case "answer":
|
|
125
|
+
await this.handleAnswer(message);
|
|
126
|
+
break;
|
|
127
|
+
case "candidate":
|
|
128
|
+
await this.handleCandidate(message);
|
|
111
129
|
break;
|
|
112
130
|
case "user-left":
|
|
113
131
|
this.emit("userLeft", message.userId);
|
|
114
132
|
break;
|
|
115
133
|
}
|
|
116
134
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
config: { iceServers: this.iceServers }
|
|
135
|
+
async createOffer() {
|
|
136
|
+
const offer = await this.pc.createOffer();
|
|
137
|
+
await this.pc.setLocalDescription(offer);
|
|
138
|
+
this.send({
|
|
139
|
+
type: "offer",
|
|
140
|
+
sdp: this.pc.localDescription
|
|
124
141
|
});
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.remoteStream = stream;
|
|
135
|
-
this.emit("remoteStream", stream);
|
|
136
|
-
if (!this.isConnectedFlag) {
|
|
137
|
-
this.isConnectedFlag = true;
|
|
138
|
-
this.emit("connected");
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
this.peer.on("connect", () => {
|
|
142
|
-
if (!this.isConnectedFlag) {
|
|
143
|
-
this.isConnectedFlag = true;
|
|
144
|
-
this.emit("connected");
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
this.peer.on("error", (err) => {
|
|
148
|
-
console.error("Peer error:", err);
|
|
142
|
+
}
|
|
143
|
+
async handleOffer(message) {
|
|
144
|
+
const offer = new RTCSessionDescription(message.sdp);
|
|
145
|
+
await this.pc.setRemoteDescription(offer);
|
|
146
|
+
const answer = await this.pc.createAnswer();
|
|
147
|
+
await this.pc.setLocalDescription(answer);
|
|
148
|
+
this.send({
|
|
149
|
+
type: "answer",
|
|
150
|
+
sdp: this.pc.localDescription
|
|
149
151
|
});
|
|
150
152
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
async handleAnswer(message) {
|
|
154
|
+
const answer = new RTCSessionDescription(message.sdp);
|
|
155
|
+
await this.pc.setRemoteDescription(answer);
|
|
156
|
+
}
|
|
157
|
+
async handleCandidate(message) {
|
|
158
|
+
const candidate = new RTCIceCandidate(message.candidate);
|
|
159
|
+
await this.pc.addIceCandidate(candidate);
|
|
156
160
|
}
|
|
157
161
|
send(data) {
|
|
158
162
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
@@ -164,10 +168,8 @@ var VoiceClient = class {
|
|
|
164
168
|
this.send({ type: "leave", roomId: this.roomId, userId: this.userId });
|
|
165
169
|
this.ws.close();
|
|
166
170
|
}
|
|
167
|
-
this.
|
|
168
|
-
|
|
169
|
-
this.localStream.getTracks().forEach((track) => track.stop());
|
|
170
|
-
}
|
|
171
|
+
this.pc?.close();
|
|
172
|
+
this.localStream?.getTracks().forEach((track) => track.stop());
|
|
171
173
|
this.isConnectedFlag = false;
|
|
172
174
|
this.emit("disconnected");
|
|
173
175
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// src/VoiceClient.ts
|
|
2
|
-
import Peer from "simple-peer";
|
|
3
2
|
var VoiceClient = class {
|
|
4
3
|
constructor(config) {
|
|
5
4
|
this.ws = null;
|
|
6
|
-
this.
|
|
5
|
+
this.pc = null;
|
|
7
6
|
this.localStream = null;
|
|
8
7
|
this.remoteStream = null;
|
|
9
8
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -33,6 +32,7 @@ var VoiceClient = class {
|
|
|
33
32
|
async connect() {
|
|
34
33
|
try {
|
|
35
34
|
await this.initMicrophone();
|
|
35
|
+
this.initPeerConnection();
|
|
36
36
|
this.initWebSocket();
|
|
37
37
|
} catch (error) {
|
|
38
38
|
this.emit("error", error);
|
|
@@ -48,75 +48,89 @@ var VoiceClient = class {
|
|
|
48
48
|
});
|
|
49
49
|
this.emit("localStream", this.localStream);
|
|
50
50
|
}
|
|
51
|
+
initPeerConnection() {
|
|
52
|
+
this.pc = new RTCPeerConnection({ iceServers: this.iceServers });
|
|
53
|
+
this.localStream?.getTracks().forEach((track) => {
|
|
54
|
+
this.pc.addTrack(track, this.localStream);
|
|
55
|
+
});
|
|
56
|
+
this.pc.ontrack = (event) => {
|
|
57
|
+
this.remoteStream = event.streams[0];
|
|
58
|
+
this.emit("remoteStream", this.remoteStream);
|
|
59
|
+
if (!this.isConnectedFlag) {
|
|
60
|
+
this.isConnectedFlag = true;
|
|
61
|
+
this.emit("connected");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
this.pc.onicecandidate = (event) => {
|
|
65
|
+
if (event.candidate) {
|
|
66
|
+
this.send({
|
|
67
|
+
type: "candidate",
|
|
68
|
+
candidate: event.candidate
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
51
73
|
initWebSocket() {
|
|
52
74
|
const url = `${this.signalingUrl}?userId=${this.userId}&roomId=${this.roomId}`;
|
|
53
75
|
this.ws = new WebSocket(url);
|
|
54
76
|
this.ws.onopen = () => {
|
|
55
77
|
this.send({ type: "join", roomId: this.roomId, userId: this.userId });
|
|
56
78
|
};
|
|
57
|
-
this.ws.onmessage = (event) => {
|
|
79
|
+
this.ws.onmessage = async (event) => {
|
|
58
80
|
const message = JSON.parse(event.data);
|
|
59
|
-
this.handleSignalingMessage(message);
|
|
81
|
+
await this.handleSignalingMessage(message);
|
|
60
82
|
};
|
|
61
83
|
this.ws.onclose = () => {
|
|
62
84
|
this.emit("disconnected");
|
|
63
85
|
};
|
|
64
86
|
}
|
|
65
|
-
handleSignalingMessage(message) {
|
|
87
|
+
async handleSignalingMessage(message) {
|
|
66
88
|
switch (message.type) {
|
|
67
89
|
case "user-joined":
|
|
68
90
|
if (message.userId !== this.userId) {
|
|
69
|
-
this.
|
|
91
|
+
await this.createOffer();
|
|
70
92
|
this.emit("userJoined", message.userId);
|
|
71
93
|
}
|
|
72
94
|
break;
|
|
73
|
-
case "
|
|
74
|
-
this.
|
|
95
|
+
case "offer":
|
|
96
|
+
await this.handleOffer(message);
|
|
97
|
+
break;
|
|
98
|
+
case "answer":
|
|
99
|
+
await this.handleAnswer(message);
|
|
100
|
+
break;
|
|
101
|
+
case "candidate":
|
|
102
|
+
await this.handleCandidate(message);
|
|
75
103
|
break;
|
|
76
104
|
case "user-left":
|
|
77
105
|
this.emit("userLeft", message.userId);
|
|
78
106
|
break;
|
|
79
107
|
}
|
|
80
108
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
config: { iceServers: this.iceServers }
|
|
109
|
+
async createOffer() {
|
|
110
|
+
const offer = await this.pc.createOffer();
|
|
111
|
+
await this.pc.setLocalDescription(offer);
|
|
112
|
+
this.send({
|
|
113
|
+
type: "offer",
|
|
114
|
+
sdp: this.pc.localDescription
|
|
88
115
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
this.remoteStream = stream;
|
|
99
|
-
this.emit("remoteStream", stream);
|
|
100
|
-
if (!this.isConnectedFlag) {
|
|
101
|
-
this.isConnectedFlag = true;
|
|
102
|
-
this.emit("connected");
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
this.peer.on("connect", () => {
|
|
106
|
-
if (!this.isConnectedFlag) {
|
|
107
|
-
this.isConnectedFlag = true;
|
|
108
|
-
this.emit("connected");
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
this.peer.on("error", (err) => {
|
|
112
|
-
console.error("Peer error:", err);
|
|
116
|
+
}
|
|
117
|
+
async handleOffer(message) {
|
|
118
|
+
const offer = new RTCSessionDescription(message.sdp);
|
|
119
|
+
await this.pc.setRemoteDescription(offer);
|
|
120
|
+
const answer = await this.pc.createAnswer();
|
|
121
|
+
await this.pc.setLocalDescription(answer);
|
|
122
|
+
this.send({
|
|
123
|
+
type: "answer",
|
|
124
|
+
sdp: this.pc.localDescription
|
|
113
125
|
});
|
|
114
126
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
async handleAnswer(message) {
|
|
128
|
+
const answer = new RTCSessionDescription(message.sdp);
|
|
129
|
+
await this.pc.setRemoteDescription(answer);
|
|
130
|
+
}
|
|
131
|
+
async handleCandidate(message) {
|
|
132
|
+
const candidate = new RTCIceCandidate(message.candidate);
|
|
133
|
+
await this.pc.addIceCandidate(candidate);
|
|
120
134
|
}
|
|
121
135
|
send(data) {
|
|
122
136
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
@@ -128,10 +142,8 @@ var VoiceClient = class {
|
|
|
128
142
|
this.send({ type: "leave", roomId: this.roomId, userId: this.userId });
|
|
129
143
|
this.ws.close();
|
|
130
144
|
}
|
|
131
|
-
this.
|
|
132
|
-
|
|
133
|
-
this.localStream.getTracks().forEach((track) => track.stop());
|
|
134
|
-
}
|
|
145
|
+
this.pc?.close();
|
|
146
|
+
this.localStream?.getTracks().forEach((track) => track.stop());
|
|
135
147
|
this.isConnectedFlag = false;
|
|
136
148
|
this.emit("disconnected");
|
|
137
149
|
}
|
package/package.json
CHANGED
package/src/VoiceClient.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import Peer from 'simple-peer';
|
|
2
|
-
|
|
3
1
|
export interface VoiceClientConfig {
|
|
4
2
|
signalingUrl: string;
|
|
5
3
|
roomId: string;
|
|
@@ -10,7 +8,7 @@ export interface VoiceClientConfig {
|
|
|
10
8
|
|
|
11
9
|
export class VoiceClient {
|
|
12
10
|
private ws: WebSocket | null = null;
|
|
13
|
-
private
|
|
11
|
+
private pc: RTCPeerConnection | null = null;
|
|
14
12
|
private localStream: MediaStream | null = null;
|
|
15
13
|
private remoteStream: MediaStream | null = null;
|
|
16
14
|
private eventHandlers: Map<string, Function[]> = new Map();
|
|
@@ -50,6 +48,7 @@ export class VoiceClient {
|
|
|
50
48
|
async connect(): Promise<void> {
|
|
51
49
|
try {
|
|
52
50
|
await this.initMicrophone();
|
|
51
|
+
this.initPeerConnection();
|
|
53
52
|
this.initWebSocket();
|
|
54
53
|
} catch (error) {
|
|
55
54
|
this.emit('error', error);
|
|
@@ -67,6 +66,32 @@ export class VoiceClient {
|
|
|
67
66
|
this.emit('localStream', this.localStream);
|
|
68
67
|
}
|
|
69
68
|
|
|
69
|
+
private initPeerConnection(): void {
|
|
70
|
+
this.pc = new RTCPeerConnection({ iceServers: this.iceServers });
|
|
71
|
+
|
|
72
|
+
this.localStream?.getTracks().forEach(track => {
|
|
73
|
+
this.pc!.addTrack(track, this.localStream!);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
this.pc.ontrack = (event) => {
|
|
77
|
+
this.remoteStream = event.streams[0];
|
|
78
|
+
this.emit('remoteStream', this.remoteStream);
|
|
79
|
+
if (!this.isConnectedFlag) {
|
|
80
|
+
this.isConnectedFlag = true;
|
|
81
|
+
this.emit('connected');
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
this.pc.onicecandidate = (event) => {
|
|
86
|
+
if (event.candidate) {
|
|
87
|
+
this.send({
|
|
88
|
+
type: 'candidate',
|
|
89
|
+
candidate: event.candidate
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
70
95
|
private initWebSocket(): void {
|
|
71
96
|
const url = `${this.signalingUrl}?userId=${this.userId}&roomId=${this.roomId}`;
|
|
72
97
|
this.ws = new WebSocket(url);
|
|
@@ -75,9 +100,9 @@ export class VoiceClient {
|
|
|
75
100
|
this.send({ type: 'join', roomId: this.roomId, userId: this.userId });
|
|
76
101
|
};
|
|
77
102
|
|
|
78
|
-
this.ws.onmessage = (event) => {
|
|
103
|
+
this.ws.onmessage = async (event) => {
|
|
79
104
|
const message = JSON.parse(event.data);
|
|
80
|
-
this.handleSignalingMessage(message);
|
|
105
|
+
await this.handleSignalingMessage(message);
|
|
81
106
|
};
|
|
82
107
|
|
|
83
108
|
this.ws.onclose = () => {
|
|
@@ -85,16 +110,22 @@ export class VoiceClient {
|
|
|
85
110
|
};
|
|
86
111
|
}
|
|
87
112
|
|
|
88
|
-
private handleSignalingMessage(message: any): void {
|
|
113
|
+
private async handleSignalingMessage(message: any): Promise<void> {
|
|
89
114
|
switch (message.type) {
|
|
90
115
|
case 'user-joined':
|
|
91
116
|
if (message.userId !== this.userId) {
|
|
92
|
-
this.
|
|
117
|
+
await this.createOffer();
|
|
93
118
|
this.emit('userJoined', message.userId);
|
|
94
119
|
}
|
|
95
120
|
break;
|
|
96
|
-
case '
|
|
97
|
-
this.
|
|
121
|
+
case 'offer':
|
|
122
|
+
await this.handleOffer(message);
|
|
123
|
+
break;
|
|
124
|
+
case 'answer':
|
|
125
|
+
await this.handleAnswer(message);
|
|
126
|
+
break;
|
|
127
|
+
case 'candidate':
|
|
128
|
+
await this.handleCandidate(message);
|
|
98
129
|
break;
|
|
99
130
|
case 'user-left':
|
|
100
131
|
this.emit('userLeft', message.userId);
|
|
@@ -102,52 +133,34 @@ export class VoiceClient {
|
|
|
102
133
|
}
|
|
103
134
|
}
|
|
104
135
|
|
|
105
|
-
private
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
stream: this.localStream || undefined,
|
|
112
|
-
config: { iceServers: this.iceServers }
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
this.peer.on('signal', (data) => {
|
|
116
|
-
this.send({
|
|
117
|
-
type: 'signal',
|
|
118
|
-
userId: this.userId,
|
|
119
|
-
roomId: this.roomId,
|
|
120
|
-
payload: data
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
this.peer.on('stream', (stream) => {
|
|
125
|
-
this.remoteStream = stream;
|
|
126
|
-
this.emit('remoteStream', stream);
|
|
127
|
-
// Когда получили удалённый поток — значит соединение установлено
|
|
128
|
-
if (!this.isConnectedFlag) {
|
|
129
|
-
this.isConnectedFlag = true;
|
|
130
|
-
this.emit('connected');
|
|
131
|
-
}
|
|
136
|
+
private async createOffer(): Promise<void> {
|
|
137
|
+
const offer = await this.pc!.createOffer();
|
|
138
|
+
await this.pc!.setLocalDescription(offer);
|
|
139
|
+
this.send({
|
|
140
|
+
type: 'offer',
|
|
141
|
+
sdp: this.pc!.localDescription
|
|
132
142
|
});
|
|
143
|
+
}
|
|
133
144
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
145
|
+
private async handleOffer(message: any): Promise<void> {
|
|
146
|
+
const offer = new RTCSessionDescription(message.sdp);
|
|
147
|
+
await this.pc!.setRemoteDescription(offer);
|
|
148
|
+
const answer = await this.pc!.createAnswer();
|
|
149
|
+
await this.pc!.setLocalDescription(answer);
|
|
150
|
+
this.send({
|
|
151
|
+
type: 'answer',
|
|
152
|
+
sdp: this.pc!.localDescription
|
|
139
153
|
});
|
|
154
|
+
}
|
|
140
155
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
private async handleAnswer(message: any): Promise<void> {
|
|
157
|
+
const answer = new RTCSessionDescription(message.sdp);
|
|
158
|
+
await this.pc!.setRemoteDescription(answer);
|
|
144
159
|
}
|
|
145
160
|
|
|
146
|
-
private
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
this.peer?.signal(signal);
|
|
161
|
+
private async handleCandidate(message: any): Promise<void> {
|
|
162
|
+
const candidate = new RTCIceCandidate(message.candidate);
|
|
163
|
+
await this.pc!.addIceCandidate(candidate);
|
|
151
164
|
}
|
|
152
165
|
|
|
153
166
|
private send(data: any): void {
|
|
@@ -161,10 +174,8 @@ export class VoiceClient {
|
|
|
161
174
|
this.send({ type: 'leave', roomId: this.roomId, userId: this.userId });
|
|
162
175
|
this.ws.close();
|
|
163
176
|
}
|
|
164
|
-
this.
|
|
165
|
-
|
|
166
|
-
this.localStream.getTracks().forEach(track => track.stop());
|
|
167
|
-
}
|
|
177
|
+
this.pc?.close();
|
|
178
|
+
this.localStream?.getTracks().forEach(track => track.stop());
|
|
168
179
|
this.isConnectedFlag = false;
|
|
169
180
|
this.emit('disconnected');
|
|
170
181
|
}
|
|
@@ -186,7 +197,6 @@ export class VoiceClient {
|
|
|
186
197
|
return this.userId;
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
|
-
|
|
190
200
|
export interface VoiceEvents {
|
|
191
201
|
connected: () => void;
|
|
192
202
|
disconnected: () => void;
|