mitmi 1.1.7 → 1.1.8

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/src/Stream.ts CHANGED
@@ -1,11 +1,17 @@
1
1
  import { Conference } from "./Conference";
2
2
  import { setLocalStream } from "./utils";
3
3
 
4
+ /**
5
+ * Stream constraints
6
+ */
4
7
  export interface StreamParams {
5
8
  audio: boolean;
6
9
  video: boolean;
7
10
  }
8
11
 
12
+ /**
13
+ * This class represent a video, camera or screenshare.
14
+ */
9
15
  class Stream {
10
16
  mediastream: MediaStream;
11
17
  domElement: undefined | HTMLVideoElement;
@@ -17,10 +23,14 @@ class Stream {
17
23
  params: StreamParams;
18
24
 
19
25
  /**
26
+ * Create a Stream
27
+ *
28
+ * @param mediastream - The video input to attach to the stream
29
+ * @param ownerId - The ownerId of the mediastream
30
+ * @param ownerName - The owner of the mediastream
20
31
  *
21
- * @param mediastream
22
- * @param owner "" => ourself, id instead
23
32
  */
33
+ //TODO Enlever le fait que ownerid est une string vide si l'owner est soit meme
24
34
  constructor(mediastream: MediaStream, ownerId: string, ownerName: string) {
25
35
  this.mediastream = mediastream;
26
36
  this.ownerId = ownerId;
@@ -29,15 +39,24 @@ class Stream {
29
39
  this.params = { audio: true, video: false };
30
40
  }
31
41
 
42
+ /**
43
+ * Check if the stream is local
44
+ *
45
+ * @returns - True if it's a localstream, false instead
46
+ */
32
47
  isLocal(): boolean {
33
48
  return this.ownerId === "";
34
49
  }
35
50
 
36
51
  /**
37
- * Will update lastest camera stream known (for DeviceMananger)
38
- * @param video
39
- * @param audio
40
- * @returns
52
+ * Get camera input
53
+ *
54
+ * @param video - Is video enable ?
55
+ * @param audio - Is audio enable ?
56
+ * @param audioDeviceId optional - Use a specific audio device
57
+ * @param videoDeviceId optional - Use a specific video device
58
+ *
59
+ * @returns A stream with your camera.
41
60
  */
42
61
  static async getCamera(
43
62
  video: boolean,
@@ -65,82 +84,97 @@ class Stream {
65
84
  }
66
85
  static getScreen() {}
67
86
 
87
+ /**
88
+ * Attach the stream to your DOM
89
+ *
90
+ * @param domElement - The HTML element to attach the stream
91
+ */
68
92
  attachToElement(domElement: HTMLVideoElement): void {
69
93
  this.domElement = domElement;
70
94
  domElement.srcObject = this.mediastream;
71
95
 
72
96
  if (this.isLocal()) {
73
- this.disableAudio();
97
+ this.localMuteAudio();
74
98
  }
75
99
  }
76
100
 
101
+ /**
102
+ * Detach the stream to your DOM
103
+ */
77
104
  detachToElement(): void {
78
105
  if (!this.domElement) return;
79
106
  this.domElement.srcObject = null;
80
107
  }
81
108
 
82
- /**
83
- * If the stream is published (so its yours) :
84
- * - video will be disabled for everyone
85
- * If the stream is not published (its yours but not publish, or other ppl stream):
86
- * - video will be disabled for you only
87
- */
88
- muteVideo() {
89
- this.params.video = false;
109
+ globalMuteVideo() {
90
110
  if (this.conferencePublish) {
91
- //your publish stream
92
- this.conferencePublish.session.socketInteraction.setConstraint(this);
111
+ this.params.video = false;
112
+ //this.conferencePublish.session.socketInteraction.setConstraint(this);
113
+ this.mediastream.getVideoTracks()[0].enabled = false;
93
114
  }
94
- this.mediastream.getVideoTracks()[0].enabled = false;
95
115
  }
96
116
 
97
- unmuteVideo() {
98
- this.params.video = true;
117
+ globalUnmuteVideo() {
99
118
  if (this.conferencePublish) {
100
- //your publish stream
101
- this.conferencePublish.session.socketInteraction.setConstraint(this);
119
+ this.params.video = true;
120
+ //this.conferencePublish.session.socketInteraction.setConstraint(this);
121
+ this.mediastream.getVideoTracks()[0].enabled = true;
102
122
  }
103
- this.mediastream.getVideoTracks()[0].enabled = true;
104
123
  }
105
124
 
106
- muteAudio(): void {
107
- this.params.audio = false;
125
+ globalMuteAudio(): void {
108
126
  if (this.conferencePublish) {
109
- this.conferencePublish.session.socketInteraction.setConstraint(this);
127
+ this.params.audio = false;
128
+ //this.conferencePublish.session.socketInteraction.setConstraint(this);
129
+ this.mediastream.getAudioTracks()[0].enabled = false;
110
130
  }
111
- this.mediastream.getAudioTracks()[0].enabled = false;
112
131
  }
113
132
 
114
- unmuteAudio(): void {
115
- this.params.audio = true;
133
+ globalUnmuteAudio(): void {
116
134
  if (this.conferencePublish) {
117
- this.conferencePublish.session.socketInteraction.setConstraint(this);
135
+ this.params.audio = true;
136
+ //this.conferencePublish.session.socketInteraction.setConstraint(this);
137
+ this.mediastream.getAudioTracks()[0].enabled = true;
118
138
  }
119
- this.mediastream.getAudioTracks()[0].enabled = true;
120
139
  }
121
140
 
122
141
  /**
123
- * This function exist to avoir Larsen.
124
- * You need to call here when a localstream is started.
142
+ * Disable local audio
125
143
  */
126
- disableAudio(): void {
144
+ localMuteAudio(): void {
127
145
  if (!this.domElement) return;
128
146
 
129
- // Important: cette ligne n'affecte pas l'envoi audio
130
147
  this.domElement.muted = true;
131
148
  this.domElement.volume = 0;
132
149
  }
133
150
 
134
151
  /**
135
- * TODO do better
152
+ * Enable local audio
136
153
  */
137
- enableAudio(): void {
154
+ localUnmuteAudio(): void {
138
155
  if (!this.domElement) return;
139
156
 
140
- // Important: cette ligne n'affecte pas l'envoi audio
141
157
  this.domElement.muted = false;
142
158
  this.domElement.volume = 1;
143
159
  }
160
+
161
+ /**
162
+ * Disable local video
163
+ */
164
+ localMuteVideo(): void {
165
+ if (!this.domElement) return;
166
+
167
+ this.domElement.pause();
168
+ }
169
+
170
+ /**
171
+ * Enable local video
172
+ */
173
+ async localUnmuteVideo(): Promise<void> {
174
+ if (!this.domElement) return;
175
+
176
+ await this.domElement.play();
177
+ }
144
178
  }
145
179
 
146
180
  export { Stream };
@@ -2,8 +2,11 @@ import { io, Socket } from "socket.io-client";
2
2
  import { serverUrl } from "../constants";
3
3
  import { getCurrentSession } from "../utils";
4
4
  import { Stream, StreamParams } from "../Stream";
5
- import { ContactInfo } from "../utils";
5
+ import { ContactInfo } from "../Contact";
6
6
 
7
+ /**
8
+ * Type of message between server and client
9
+ */
7
10
  interface SocketMessage {
8
11
  from: ContactInfo;
9
12
  target?: string;
@@ -16,6 +19,12 @@ interface SocketMessage {
16
19
  };
17
20
  }
18
21
 
22
+ /**
23
+ * Main interaction between socket and server
24
+ *
25
+ * @private
26
+ *
27
+ */
19
28
  export class SocketInteraction extends EventTarget {
20
29
  private socket!: Socket;
21
30
  private _userId?: string;
@@ -45,6 +54,12 @@ export class SocketInteraction extends EventTarget {
45
54
  return this._userId;
46
55
  }
47
56
 
57
+ /**
58
+ * Publish a Stream into all peers
59
+ *
60
+ * @param stream - Stream to publish
61
+ */
62
+ //TODO Check to publish multiple stream, ATM => one at the moment
48
63
  publish(stream: Stream) {
49
64
  this.localStream = stream;
50
65
 
@@ -55,6 +70,11 @@ export class SocketInteraction extends EventTarget {
55
70
  console.log("[RTC] Stream published to all peers");
56
71
  }
57
72
 
73
+ /**
74
+ * Unbuplish stream into all peers
75
+ *
76
+ * @param stream - Stream to unpublish
77
+ */
58
78
  unpublish(stream: Stream) {
59
79
  if (this.localStream != stream) throw new Error("this is not your stream");
60
80
  this.localStream = undefined;
@@ -67,8 +87,10 @@ export class SocketInteraction extends EventTarget {
67
87
  }
68
88
 
69
89
  /**
90
+ * Set constraint to you stream ex : muteAudio
91
+ * Stream have stream.params, use to set constraint on the peer
70
92
  *
71
- * @param stream Stream have stream.params, use to set constraint on the peer
93
+ * @param stream - Affected Stream with constraints
72
94
  */
73
95
  setConstraint(stream: Stream) {
74
96
  if (this.localStream != stream) throw new Error("this is not your stream");
@@ -91,6 +113,13 @@ export class SocketInteraction extends EventTarget {
91
113
  console.log("[RTC] Set constraint");
92
114
  }
93
115
 
116
+ /**
117
+ * Attach a stream to a peer
118
+ *
119
+ * @param pc - PeerConnection to attach this.localstream
120
+ * @returns
121
+ */
122
+ //TODO don't use this.localstream, but a parameter instead ?
94
123
  private attachStreamToPeer(pc: RTCPeerConnection) {
95
124
  if (!this.localStream) return;
96
125
 
@@ -100,6 +129,13 @@ export class SocketInteraction extends EventTarget {
100
129
  });
101
130
  }
102
131
 
132
+ /**
133
+ * Detach a stream to a peer
134
+ *
135
+ * @param pc - PeerConnection to detach this.localstream
136
+ * @returns
137
+ */
138
+ //TODO don't use this.localstream, but a parameter instead ?
103
139
  private removeStreamToPeer(pc: RTCPeerConnection) {
104
140
  if (!this.localStream) return;
105
141
 
@@ -108,6 +144,13 @@ export class SocketInteraction extends EventTarget {
108
144
  });
109
145
  }
110
146
 
147
+ /**
148
+ * Stop sending a specific track
149
+ *
150
+ * @param pc - Affected Peerconnection
151
+ * @param track - Track to disable
152
+ * @returns
153
+ */
111
154
  private disableTrackToPeer(pc: RTCPeerConnection, track: MediaStreamTrack) {
112
155
  if (!this.localStream) return;
113
156
 
@@ -120,6 +163,13 @@ export class SocketInteraction extends EventTarget {
120
163
  });
121
164
  }
122
165
 
166
+ /**
167
+ * Activate a track into a peer
168
+ *
169
+ * @param pc - Affected Peerconnection
170
+ * @param track - Track to enable
171
+ * @returns
172
+ */
123
173
  private enableTrackToPeer(pc: RTCPeerConnection, track: MediaStreamTrack) {
124
174
  if (!this.localStream) return;
125
175
 
@@ -132,6 +182,11 @@ export class SocketInteraction extends EventTarget {
132
182
  });
133
183
  }
134
184
 
185
+ /**
186
+ * Send a join message to the server
187
+ *
188
+ * @param confId - ID conference
189
+ */
135
190
  register(confId: number) {
136
191
  /*if (!this.publishStream) {
137
192
  throw new Error("Call publish() before register()");
@@ -147,7 +202,15 @@ export class SocketInteraction extends EventTarget {
147
202
  console.log(`[CONF] Join request sent for room ${confId}`);
148
203
  }
149
204
 
205
+ /**
206
+ * Disconnect
207
+ */
150
208
  unregister() {
209
+ //Stop all the track before (release camera and microphone)
210
+ if (this.localStream) {
211
+ this.localStream.mediastream.getTracks().forEach((track) => track.stop());
212
+ }
213
+
151
214
  Object.values(this.peerConnections).forEach((pc) => pc.close());
152
215
  this.peerConnections = {};
153
216
 
@@ -157,6 +220,11 @@ export class SocketInteraction extends EventTarget {
157
220
  console.log("[CONF] Unregistered and socket closed");
158
221
  }
159
222
 
223
+ /**
224
+ * Set Listeners
225
+ *
226
+ * @private
227
+ */
160
228
  private setupSocketListeners() {
161
229
  this.socket.on("message", async (message: SocketMessage) => {
162
230
  if (!this._confId) return;
@@ -199,6 +267,13 @@ export class SocketInteraction extends EventTarget {
199
267
  });
200
268
  }
201
269
 
270
+ /**
271
+ * Create a Peerconnection with the remote contact
272
+ *
273
+ * @param from - Peerconnection with this contact
274
+ * @param initiator - Are you the applicant
275
+ * @returns
276
+ */
202
277
  private async createPeerConnection(from: ContactInfo, initiator: boolean) {
203
278
  const remoteUserId = from.id;
204
279
  const remoteUserName = from.name;
@@ -249,6 +324,12 @@ export class SocketInteraction extends EventTarget {
249
324
  }
250
325
  }
251
326
 
327
+ /**
328
+ * Event handle the offer
329
+ *
330
+ * @param from - Contact who send the offer
331
+ * @param sdp - Offer
332
+ */
252
333
  private async handleOffer(from: ContactInfo, sdp: RTCSessionDescriptionInit) {
253
334
  const remoteUserId = from.id;
254
335
  await this.createPeerConnection(from, false);
@@ -277,6 +358,13 @@ export class SocketInteraction extends EventTarget {
277
358
  this.dispatchEvent(event);
278
359
  }
279
360
 
361
+ /**
362
+ * Event handle the enswer
363
+ *
364
+ * @param from - Contact who send tjhe answer
365
+ * @param sdp - The answer
366
+ * @returns
367
+ */
280
368
  private async handleAnswer(
281
369
  from: ContactInfo,
282
370
  sdp: RTCSessionDescriptionInit
@@ -294,6 +382,13 @@ export class SocketInteraction extends EventTarget {
294
382
  this.dispatchEvent(event);
295
383
  }
296
384
 
385
+ /**
386
+ * Event when receive ice candidates
387
+ *
388
+ * @param from - Contact
389
+ * @param candidate - Icecandidate
390
+ * @returns
391
+ */
297
392
  private async handleIce(from: ContactInfo, candidate: RTCIceCandidate) {
298
393
  const remoteUserId = from.id;
299
394
  const pc = this.peerConnections[remoteUserId];
@@ -302,11 +397,21 @@ export class SocketInteraction extends EventTarget {
302
397
  await pc.addIceCandidate(candidate);
303
398
  }
304
399
 
400
+ /**
401
+ * Event when receive a disconnection message
402
+ *
403
+ * @param remoteId - ID that leave
404
+ */
305
405
  private removePeer(remoteId: string) {
306
406
  this.peerConnections[remoteId]?.close();
307
407
  delete this.peerConnections[remoteId];
308
408
  }
309
409
 
410
+ /**
411
+ * Send a message on the socket
412
+ *
413
+ * @param msg - Message to send on the socket
414
+ */
310
415
  private sendMessage(msg: SocketMessage) {
311
416
  this.socket.emit("message", msg);
312
417
  }
package/src/index.ts CHANGED
@@ -4,3 +4,7 @@ export { HelloWorld } from "./HelloWorld";
4
4
  export { Stream } from "./Stream";
5
5
  export { Conference } from "./Conference";
6
6
  export { DeviceManager } from "./DeviceManager";
7
+
8
+ //Interfaces
9
+ export type { StreamParams } from "./Stream";
10
+ export type { ContactInfo } from "./Contact";
package/src/utils.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import { Session } from "./Session";
2
2
  import { Stream } from "./Stream";
3
3
 
4
+ /**
5
+ * Generate a random string
6
+ *
7
+ * @returns - A random string format, ex: de0b1c44-b42e-c617-bcc2-14586c5fffe2
8
+ */
4
9
  function uidGenerator(): String {
5
10
  var S4 = function () {
6
11
  return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
@@ -21,6 +26,9 @@ function uidGenerator(): String {
21
26
  );
22
27
  }
23
28
 
29
+ /**
30
+ * Function for global session
31
+ */
24
32
  let currentSession: Session | undefined = undefined;
25
33
  function setCurrentSession(newSession: undefined | Session) {
26
34
  currentSession = newSession;
@@ -29,6 +37,10 @@ function getCurrentSession() {
29
37
  return currentSession;
30
38
  }
31
39
 
40
+ //TODO Useless ?
41
+ /**
42
+ * Function for localstream
43
+ */
32
44
  let localStream: Stream | undefined = undefined;
33
45
  function setLocalStream(newStream: undefined | Stream) {
34
46
  localStream = newStream;
@@ -37,12 +49,6 @@ function getLocalStream() {
37
49
  return localStream;
38
50
  }
39
51
 
40
- interface ContactInfo {
41
- id: string;
42
- name: string;
43
- }
44
-
45
- export { ContactInfo };
46
52
  export { setCurrentSession };
47
53
  export { getCurrentSession };
48
54
  export { setLocalStream };