warpr 1.0.10 → 1.0.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "warpr",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Warper is a WebRTC based ultra-low latency video streaming library.",
6
6
  "peerDependencies": {
@@ -11,8 +11,35 @@ export class ConnectionRequest {
11
11
  public readonly $type = WarprSignalingMessageType.ConnectionRequest;
12
12
  public SessionId?: string;
13
13
  }
14
+
14
15
  export class PairingCompleteMessage {
15
16
  public readonly $type = WarprSignalingMessageType.PairingCompleteMessage;
17
+
18
+ public IceServers?: string[];
19
+ }
20
+
21
+ export function GetConfiguration(iceServers?: string[]): RTCConfiguration {
22
+ let result: RTCConfiguration = {};
23
+ result.iceServers = new Array<RTCIceServer>();
24
+
25
+ if (iceServers) {
26
+ let regex = /^(?<protocol>stun|turn):(?:(?<username>\w+):(?<password>\w+)@)?(?<url>[\w\.:?=&]+)$/im;
27
+ for (let server of iceServers) {
28
+ let match = regex.exec(server);
29
+ if (!match || !match.groups) {
30
+ console.warn(`Failed to parse ICE server URI ${server}.`);
31
+ continue;
32
+ }
33
+
34
+ result.iceServers.push({
35
+ urls: `${match.groups['protocol']}:${match.groups['url']}`,
36
+ username: match.groups['username'],
37
+ credential: match.groups['password']
38
+ });
39
+ }
40
+ }
41
+
42
+ return result;
16
43
  }
17
44
 
18
45
  export class PeerConnectionDescriptionMessage {
@@ -2,17 +2,20 @@ import { EventOwner, EventPublisher, EventArgs } from "../infrastructure/events"
2
2
  import { IMessagingClient } from "./messaging-client";
3
3
 
4
4
  export class WebSocketClient<TMessage> implements IMessagingClient<TMessage> {
5
- private readonly _socket: WebSocket;
6
5
  private readonly _events = new EventOwner();
7
6
 
8
7
  public readonly Connected = new EventPublisher<IMessagingClient<TMessage>, EventArgs>(this._events);
9
8
  public readonly MessageReceived = new EventPublisher<IMessagingClient<TMessage>, TMessage>(this._events);
10
9
  public readonly Disconnected = new EventPublisher<IMessagingClient<TMessage>, EventArgs>(this._events);
11
10
 
12
- constructor(uri: string) {
13
- console.log(`Connecting to ${uri}...`);
11
+ private _socket?: WebSocket;
14
12
 
15
- let socket = new WebSocket(uri);
13
+ constructor(private _uri: string) { }
14
+
15
+ Connect(): void {
16
+ console.log(`Connecting to ${this._uri}...`);
17
+
18
+ let socket = new WebSocket(this._uri);
16
19
  socket.onopen = () => this.OnConnected();
17
20
  socket.onmessage = (e: MessageEvent<string>) => this.OnMessageReceived(e);
18
21
  socket.onclose = () => this.OnDisconnected();
@@ -21,26 +24,28 @@ export class WebSocketClient<TMessage> implements IMessagingClient<TMessage> {
21
24
  }
22
25
 
23
26
  SendMessage(message: TMessage): void {
27
+ if (!this._socket) return;
28
+
24
29
  let content = JSON.stringify(message);
25
- console.log(`Sending message: ${content}`);
30
+ console.debug(`Sending message: ${content}`);
26
31
 
27
32
  this._socket.send(content);
28
33
  }
29
34
 
30
35
  protected OnConnected(): void {
31
- console.log(`Connected to: ${this._socket.url}.`);
36
+ console.log(`Connected to: ${this._uri}.`);
32
37
  this._events.Raise(this.Connected, this, EventArgs.Empty);
33
38
  }
34
39
 
35
40
  protected OnMessageReceived(eventArgs: MessageEvent<string>): void {
36
- console.log('Message received: ' + eventArgs.data);
41
+ console.debug('Message received: ' + eventArgs.data);
37
42
 
38
43
  let message = JSON.parse(eventArgs.data) as TMessage;
39
44
  this._events.Raise(this.MessageReceived, this, message);
40
45
  }
41
46
 
42
47
  protected OnDisconnected(): void {
43
- console.log(`Disconnected from: ${this._socket.url}.`);
48
+ console.log(`Disconnected from: ${this._uri}.`);
44
49
  this._events.Raise(this.Disconnected, this, EventArgs.Empty);
45
50
  }
46
51
 
@@ -1,8 +1,8 @@
1
1
  import { Injectable } from '@angular/core';
2
2
  import { MessagingService } from './messaging.service';
3
- import { PeerConnectionCandidateMessage, PeerConnectionDescriptionMessage, WarprSignalingMessage, WarprSignalingMessageType } from '../data/signaling-messages';
3
+ import { GetConfiguration, PairingCompleteMessage, PeerConnectionCandidateMessage, PeerConnectionDescriptionMessage, WarprSignalingMessage, WarprSignalingMessageType } from '../data/signaling-messages';
4
4
  import { IMessagingClient } from '../networking/messaging-client';
5
- import { EncodedFrame, FrameType } from '../data/frames';
5
+ import { EncodedFrame } from '../data/frames';
6
6
  import { EventOwner, EventPublisher } from '../infrastructure/events';
7
7
  import { MessageAssembler } from '../infrastructure/message-assembler';
8
8
 
@@ -20,48 +20,22 @@ export class StreamingService {
20
20
  public readonly FrameReceived = new EventPublisher<StreamingService, EncodedFrame>(this._events);
21
21
  public readonly Connected = new EventPublisher<StreamingService, any>(this._events);
22
22
 
23
- private static _config: RTCConfiguration = {
24
- iceServers: [
25
- { urls: "stun:stun.l.google.com:19302" },
26
- { urls: "stun:stun.relay.metered.ca:80" },
27
- {
28
- urls: "turn:global.relay.metered.ca:80",
29
- username: "cb51ef701a61be3cdc89466f",
30
- credential: "BBnGCvnTLaxhVbuf"
31
- },
32
- {
33
- urls: "turn:global.relay.metered.ca:80?transport=tcp",
34
- username: "cb51ef701a61be3cdc89466f",
35
- credential: "BBnGCvnTLaxhVbuf"
36
- },
37
- {
38
- urls: "turn:global.relay.metered.ca:443",
39
- username: "cb51ef701a61be3cdc89466f",
40
- credential: "BBnGCvnTLaxhVbuf"
41
- },
42
- {
43
- urls: "turns:global.relay.metered.ca:443?transport=tcp",
44
- username: "cb51ef701a61be3cdc89466f",
45
- credential: "BBnGCvnTLaxhVbuf"
46
- }
47
- ]
48
- };
49
-
50
23
  constructor(
51
24
  private _messagingService: MessagingService) {
52
25
 
53
26
  _messagingService.MessageReceived.Subscribe((sender: IMessagingClient<WarprSignalingMessage>, message: WarprSignalingMessage) => this.OnMessageReceived(sender, message));
54
-
55
- this.Reconnect();
27
+ _messagingService.Connect();
56
28
  }
57
29
 
58
- private Reconnect() {
30
+ private Reconnect(configuration: RTCConfiguration) {
31
+ console.log("Establishing peer connection...");
32
+
59
33
  this._reliableConnection?.close();
60
34
  this._lowLatencyConnection?.close();
61
35
  this._peerConnection?.close();
62
36
  this._messageBuilder = new MessageAssembler();
63
37
 
64
- this._peerConnection = new RTCPeerConnection(StreamingService._config);
38
+ this._peerConnection = new RTCPeerConnection(configuration);
65
39
  this._peerConnection.onicecandidate = (event) => this.OnIceCandidateAdded(event.candidate?.candidate);
66
40
  this._peerConnection.ondatachannel = (event) => this.OnDataChannel(event);
67
41
  this._peerConnection.onconnectionstatechange = (event) => this.OnConnectionStateChanged();
@@ -107,7 +81,7 @@ export class StreamingService {
107
81
  if (elapsed > 1000) {
108
82
  this._lastRefreshTime = now;
109
83
 
110
- console.log(`Messages: ${this._count / elapsed * 1000} FPS`);
84
+ console.debug(`Messages: ${this._count / elapsed * 1000} FPS`);
111
85
  this._count = 0;
112
86
  }
113
87
 
@@ -125,13 +99,13 @@ export class StreamingService {
125
99
 
126
100
  private async OnMessageReceived(sender: IMessagingClient<WarprSignalingMessage>, message: WarprSignalingMessage) {
127
101
 
128
- if (!this._peerConnection) return;
129
-
130
102
  switch (message.$type) {
131
103
  case WarprSignalingMessageType.PairingCompleteMessage:
132
- this.Reconnect();
104
+ this.Reconnect(GetConfiguration(message.IceServers));
133
105
  break;
134
106
  case WarprSignalingMessageType.PeerConnectionDescriptionMessage:
107
+ if (!this._peerConnection) return;
108
+
135
109
  await this._peerConnection.setRemoteDescription({ type: "offer", sdp: message.Description });
136
110
  let answer = await this._peerConnection.createAnswer();
137
111
  await this._peerConnection.setLocalDescription(answer);
@@ -142,6 +116,8 @@ export class StreamingService {
142
116
 
143
117
  break;
144
118
  case WarprSignalingMessageType.PeerConnectionCandidateMessage:
119
+ if (!this._peerConnection) return;
120
+
145
121
  await this._peerConnection.addIceCandidate({ candidate: message.Candidate, sdpMid: "0" });
146
122
  break;
147
123
  }
Binary file
package/warpr-1.0.10.tgz DELETED
Binary file