ring-client-api 10.0.0-beta.7 → 11.0.0
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/CHANGELOG.md +64 -0
- package/lib/api/api.js +79 -96
- package/lib/api/device-data.js +20 -31
- package/lib/api/location.js +125 -157
- package/lib/api/refresh-token.js +23 -36
- package/lib/api/rest-client.js +159 -165
- package/lib/api/ring-camera.js +121 -157
- package/lib/api/ring-chime.js +32 -51
- package/lib/api/ring-device.js +4 -1
- package/lib/api/streaming/peer-connection.js +11 -26
- package/lib/api/streaming/ring-edge-connection.js +56 -65
- package/lib/api/streaming/simple-webrtc-session.js +27 -42
- package/lib/api/streaming/streaming-connection-base.js +12 -25
- package/lib/api/streaming/streaming-session.js +56 -73
- package/lib/api/streaming/webrtc-connection.js +22 -30
- package/lib/api/util.js +35 -39
- package/package.json +2 -4
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.RingEdgeConnection = void 0;
|
|
13
4
|
const ws_1 = require("ws");
|
|
@@ -56,8 +47,8 @@ class RingEdgeConnection extends streaming_connection_base_1.StreamingConnection
|
|
|
56
47
|
return;
|
|
57
48
|
}
|
|
58
49
|
this.sendSessionMessage('ping');
|
|
59
|
-
}), this.pc.onIceCandidate.subscribe((iceCandidate) =>
|
|
60
|
-
|
|
50
|
+
}), this.pc.onIceCandidate.subscribe(async (iceCandidate) => {
|
|
51
|
+
await (0, rxjs_1.firstValueFrom)(this.onOfferSent);
|
|
61
52
|
this.sendMessage({
|
|
62
53
|
method: 'ice',
|
|
63
54
|
body: {
|
|
@@ -76,69 +67,69 @@ class RingEdgeConnection extends streaming_connection_base_1.StreamingConnection
|
|
|
76
67
|
mlineindex: 1,
|
|
77
68
|
},
|
|
78
69
|
});
|
|
79
|
-
}))
|
|
70
|
+
}));
|
|
80
71
|
}
|
|
81
|
-
initiateCall() {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
this.onOfferSent.next();
|
|
72
|
+
async initiateCall() {
|
|
73
|
+
const { sdp } = await this.pc.createOffer();
|
|
74
|
+
this.sendMessage({
|
|
75
|
+
method: 'live_view',
|
|
76
|
+
body: {
|
|
77
|
+
doorbot_id: this.camera.id,
|
|
78
|
+
stream_options: { audio_enabled: true, video_enabled: true },
|
|
79
|
+
sdp: sdp.replace('\na=group:BUNDLE 0 1', ''),
|
|
80
|
+
},
|
|
93
81
|
});
|
|
82
|
+
this.onOfferSent.next();
|
|
94
83
|
}
|
|
95
|
-
handleMessage(message) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
84
|
+
async handleMessage(message) {
|
|
85
|
+
if (message.body.doorbot_id !== this.camera.id) {
|
|
86
|
+
// ignore messages for other cameras
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (['session_created', 'session_started'].includes(message.method) &&
|
|
90
|
+
'session_id' in message.body &&
|
|
91
|
+
!this.sessionId) {
|
|
92
|
+
this.sessionId = message.body.session_id;
|
|
93
|
+
this.onSessionId.next(this.sessionId);
|
|
94
|
+
}
|
|
95
|
+
if (message.body.session_id && message.body.session_id !== this.sessionId) {
|
|
96
|
+
// ignore messages for other sessions
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
switch (message.method) {
|
|
100
|
+
case 'session_created':
|
|
101
|
+
case 'session_started':
|
|
102
|
+
// session already stored above
|
|
99
103
|
return;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
!this.sessionId) {
|
|
104
|
-
this.sessionId = message.body.session_id;
|
|
105
|
-
this.onSessionId.next(this.sessionId);
|
|
106
|
-
}
|
|
107
|
-
if (message.body.session_id && message.body.session_id !== this.sessionId) {
|
|
108
|
-
// ignore messages for other sessions
|
|
104
|
+
case 'sdp':
|
|
105
|
+
await this.pc.acceptAnswer(message.body);
|
|
106
|
+
this.onCallAnswered.next(message.body.sdp);
|
|
109
107
|
return;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
case 'pong':
|
|
127
|
-
return;
|
|
128
|
-
case 'close':
|
|
129
|
-
(0, util_1.logError)('Video stream closed');
|
|
130
|
-
(0, util_1.logError)(message.body);
|
|
131
|
-
this.callEnded();
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
(0, util_1.logError)('UNKNOWN MESSAGE');
|
|
135
|
-
(0, util_1.logError)(message);
|
|
136
|
-
});
|
|
108
|
+
case 'ice':
|
|
109
|
+
await this.pc.addIceCandidate({
|
|
110
|
+
candidate: message.body.ice,
|
|
111
|
+
sdpMLineIndex: message.body.mlineindex,
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
case 'pong':
|
|
115
|
+
return;
|
|
116
|
+
case 'close':
|
|
117
|
+
(0, util_1.logError)('Video stream closed');
|
|
118
|
+
(0, util_1.logError)(message.body);
|
|
119
|
+
this.callEnded();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
(0, util_1.logError)('UNKNOWN MESSAGE');
|
|
123
|
+
(0, util_1.logError)(message);
|
|
137
124
|
}
|
|
138
125
|
sendSessionMessage(method, body = {}) {
|
|
139
126
|
const message = {
|
|
140
127
|
method,
|
|
141
|
-
body:
|
|
128
|
+
body: {
|
|
129
|
+
...body,
|
|
130
|
+
doorbot_id: this.camera.id,
|
|
131
|
+
session_id: this.sessionId,
|
|
132
|
+
},
|
|
142
133
|
};
|
|
143
134
|
if (this.sessionId) {
|
|
144
135
|
// Send immediately if we already have a session id
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.SimpleWebRtcSession = void 0;
|
|
13
4
|
const util_1 = require("../util");
|
|
@@ -20,43 +11,37 @@ class SimpleWebRtcSession {
|
|
|
20
11
|
this.restClient = restClient;
|
|
21
12
|
this.sessionId = (0, util_1.generateUuid)();
|
|
22
13
|
}
|
|
23
|
-
start(sdp) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
return response.sdp;
|
|
14
|
+
async start(sdp) {
|
|
15
|
+
const response = await this.restClient.request({
|
|
16
|
+
method: 'POST',
|
|
17
|
+
url: liveViewUrl('start'),
|
|
18
|
+
json: {
|
|
19
|
+
session_id: this.sessionId,
|
|
20
|
+
device_id: this.camera.id,
|
|
21
|
+
sdp,
|
|
22
|
+
protocol: 'webrtc',
|
|
23
|
+
},
|
|
36
24
|
});
|
|
25
|
+
return response.sdp;
|
|
37
26
|
}
|
|
38
|
-
end() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
return resp;
|
|
27
|
+
async end() {
|
|
28
|
+
const resp = await this.restClient.request({
|
|
29
|
+
method: 'POST',
|
|
30
|
+
url: liveViewUrl('end'),
|
|
31
|
+
json: {
|
|
32
|
+
session_id: this.sessionId,
|
|
33
|
+
},
|
|
48
34
|
});
|
|
35
|
+
return resp;
|
|
49
36
|
}
|
|
50
|
-
activateCameraSpeaker() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
59
|
-
});
|
|
37
|
+
async activateCameraSpeaker() {
|
|
38
|
+
await this.restClient.request({
|
|
39
|
+
method: 'PATCH',
|
|
40
|
+
url: liveViewUrl('options'),
|
|
41
|
+
json: {
|
|
42
|
+
session_id: this.sessionId,
|
|
43
|
+
actions: ['turn_off_stealth_mode'],
|
|
44
|
+
},
|
|
60
45
|
});
|
|
61
46
|
}
|
|
62
47
|
}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.StreamingConnectionBase = void 0;
|
|
13
4
|
const peer_connection_1 = require("./peer-connection");
|
|
@@ -59,23 +50,19 @@ class StreamingConnectionBase extends subscribed_1.Subscribed {
|
|
|
59
50
|
}
|
|
60
51
|
}));
|
|
61
52
|
}
|
|
62
|
-
activate() {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this.sendSessionMessage('activate_session');
|
|
71
|
-
});
|
|
53
|
+
async activate() {
|
|
54
|
+
if (this.activated) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.activated = true;
|
|
58
|
+
await (0, rxjs_1.firstValueFrom)(this.pc.onConnectionState.pipe((0, operators_1.filter)((state) => state === 'connected')));
|
|
59
|
+
(0, util_1.logInfo)('Activating Session');
|
|
60
|
+
this.sendSessionMessage('activate_session');
|
|
72
61
|
}
|
|
73
|
-
activateCameraSpeaker() {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
stealth_mode: false,
|
|
78
|
-
});
|
|
62
|
+
async activateCameraSpeaker() {
|
|
63
|
+
await (0, rxjs_1.firstValueFrom)(this.onCallAnswered);
|
|
64
|
+
this.sendSessionMessage('camera_options', {
|
|
65
|
+
stealth_mode: false,
|
|
79
66
|
});
|
|
80
67
|
}
|
|
81
68
|
sendMessage(message) {
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.StreamingSession = void 0;
|
|
13
4
|
const camera_utils_1 = require("@homebridge/camera-utils");
|
|
@@ -41,78 +32,70 @@ class StreamingSession extends subscribed_1.Subscribed {
|
|
|
41
32
|
bindToConnection(connection) {
|
|
42
33
|
this.addSubscriptions(connection.onAudioRtp.subscribe(this.onAudioRtp), connection.onVideoRtp.subscribe(this.onVideoRtp));
|
|
43
34
|
}
|
|
44
|
-
activate() {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
yield this.connection.activate();
|
|
51
|
-
});
|
|
35
|
+
async activate() {
|
|
36
|
+
if (this.activated) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.activated = true;
|
|
40
|
+
await this.connection.activate();
|
|
52
41
|
}
|
|
53
|
-
activateCameraSpeaker() {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
yield this.connection.activateCameraSpeaker();
|
|
60
|
-
});
|
|
42
|
+
async activateCameraSpeaker() {
|
|
43
|
+
if (this.cameraSpeakerActivated) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.cameraSpeakerActivated = true;
|
|
47
|
+
await this.connection.activateCameraSpeaker();
|
|
61
48
|
}
|
|
62
|
-
reservePort(bufferPorts = 0) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return ports[0];
|
|
66
|
-
});
|
|
49
|
+
async reservePort(bufferPorts = 0) {
|
|
50
|
+
const ports = await (0, camera_utils_1.reservePorts)({ count: bufferPorts + 1 });
|
|
51
|
+
return ports[0];
|
|
67
52
|
}
|
|
68
|
-
startTranscoding(ffmpegOptions) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
53
|
+
async startTranscoding(ffmpegOptions) {
|
|
54
|
+
const videoPort = await this.reservePort(1), audioPort = await this.reservePort(1), transcodeVideoStream = ffmpegOptions.video !== false, ffmpegInputArguments = [
|
|
55
|
+
'-hide_banner',
|
|
56
|
+
'-protocol_whitelist',
|
|
57
|
+
'pipe,udp,rtp,file,crypto',
|
|
58
|
+
'-acodec',
|
|
59
|
+
'libopus',
|
|
60
|
+
'-f',
|
|
61
|
+
'sdp',
|
|
62
|
+
...(ffmpegOptions.input || []),
|
|
63
|
+
'-i',
|
|
64
|
+
'pipe:',
|
|
65
|
+
], ringSdp = await (0, rxjs_1.firstValueFrom)(this.connection.onCallAnswered), inputSdp = getCleanSdp(ringSdp, transcodeVideoStream)
|
|
66
|
+
.replace(/m=audio \d+/, `m=audio ${audioPort}`)
|
|
67
|
+
.replace(/m=video \d+/, `m=video ${videoPort}`), ff = new camera_utils_1.FfmpegProcess({
|
|
68
|
+
ffmpegArgs: ffmpegInputArguments.concat(...(ffmpegOptions.audio || ['-acodec', 'aac']), ...(transcodeVideoStream
|
|
69
|
+
? ffmpegOptions.video || ['-vcodec', 'copy']
|
|
70
|
+
: []), ...(ffmpegOptions.output || [])),
|
|
71
|
+
ffmpegPath: (0, ffmpeg_1.getFfmpegPath)(),
|
|
72
|
+
exitCallback: () => this.callEnded(),
|
|
73
|
+
logLabel: `From Ring (${this.camera.name})`,
|
|
74
|
+
logger: {
|
|
75
|
+
error: util_1.logError,
|
|
76
|
+
info: util_1.logDebug,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
this.addSubscriptions(this.onAudioRtp
|
|
80
|
+
.pipe((0, operators_1.concatMap)((rtp) => {
|
|
81
|
+
return this.audioSplitter.send(rtp.serialize(), {
|
|
82
|
+
port: audioPort,
|
|
94
83
|
});
|
|
95
|
-
|
|
84
|
+
}))
|
|
85
|
+
.subscribe());
|
|
86
|
+
if (transcodeVideoStream) {
|
|
87
|
+
this.addSubscriptions(this.onVideoRtp
|
|
96
88
|
.pipe((0, operators_1.concatMap)((rtp) => {
|
|
97
|
-
return this.
|
|
98
|
-
port:
|
|
89
|
+
return this.videoSplitter.send(rtp.serialize(), {
|
|
90
|
+
port: videoPort,
|
|
99
91
|
});
|
|
100
92
|
}))
|
|
101
93
|
.subscribe());
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
});
|
|
108
|
-
}))
|
|
109
|
-
.subscribe());
|
|
110
|
-
}
|
|
111
|
-
this.onCallEnded.subscribe(() => ff.stop());
|
|
112
|
-
ff.writeStdin(inputSdp);
|
|
113
|
-
// Activate the stream now that ffmpeg is ready to receive
|
|
114
|
-
yield this.activate();
|
|
115
|
-
});
|
|
94
|
+
}
|
|
95
|
+
this.onCallEnded.subscribe(() => ff.stop());
|
|
96
|
+
ff.writeStdin(inputSdp);
|
|
97
|
+
// Activate the stream now that ffmpeg is ready to receive
|
|
98
|
+
await this.activate();
|
|
116
99
|
}
|
|
117
100
|
callEnded() {
|
|
118
101
|
this.unsubscribe();
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.WebrtcConnection = void 0;
|
|
13
4
|
const ws_1 = require("ws");
|
|
@@ -32,29 +23,30 @@ class WebrtcConnection extends streaming_connection_base_1.StreamingConnectionBa
|
|
|
32
23
|
(0, util_1.logDebug)(`WebSocket connected for ${camera.name}`);
|
|
33
24
|
}));
|
|
34
25
|
}
|
|
35
|
-
handleMessage(message) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
});
|
|
26
|
+
async handleMessage(message) {
|
|
27
|
+
switch (message.method) {
|
|
28
|
+
case 'sdp':
|
|
29
|
+
const answer = await this.pc.createAnswer(message);
|
|
30
|
+
this.sendSessionMessage('sdp', answer);
|
|
31
|
+
this.onCallAnswered.next(message.sdp);
|
|
32
|
+
this.sendSessionMessage('stream_options', {
|
|
33
|
+
audio_enabled: true,
|
|
34
|
+
video_enabled: true,
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
case 'ice':
|
|
38
|
+
await this.pc.addIceCandidate({
|
|
39
|
+
candidate: message.ice,
|
|
40
|
+
sdpMLineIndex: message.mlineindex,
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
55
44
|
}
|
|
56
45
|
sendSessionMessage(method, body = {}) {
|
|
57
|
-
this.sendMessage(
|
|
46
|
+
this.sendMessage({
|
|
47
|
+
...body,
|
|
48
|
+
method,
|
|
49
|
+
});
|
|
58
50
|
}
|
|
59
51
|
}
|
|
60
52
|
exports.WebrtcConnection = WebrtcConnection;
|
package/lib/api/util.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -63,39 +54,35 @@ function generateUuid(seed) {
|
|
|
63
54
|
return (0, uuid_1.v4)();
|
|
64
55
|
}
|
|
65
56
|
exports.generateUuid = generateUuid;
|
|
66
|
-
function getHardwareId(systemId) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return generateUuid(id);
|
|
85
|
-
});
|
|
57
|
+
async function getHardwareId(systemId) {
|
|
58
|
+
if (systemId) {
|
|
59
|
+
return generateUuid(systemId);
|
|
60
|
+
}
|
|
61
|
+
const timeoutValue = '-1', { os: id } = await Promise.race([
|
|
62
|
+
(0, systeminformation_1.uuid)(),
|
|
63
|
+
delay(5000).then(() => ({ os: timeoutValue })),
|
|
64
|
+
]);
|
|
65
|
+
if (id === timeoutValue) {
|
|
66
|
+
logError('Request for system uuid timed out. Falling back to random session id');
|
|
67
|
+
return (0, uuid_1.v4)();
|
|
68
|
+
}
|
|
69
|
+
if (id === '-') {
|
|
70
|
+
// default value set by systeminformation if it can't find a real value
|
|
71
|
+
logError('Unable to get system uuid. Falling back to random session id');
|
|
72
|
+
return (0, uuid_1.v4)();
|
|
73
|
+
}
|
|
74
|
+
return generateUuid(id);
|
|
86
75
|
}
|
|
87
76
|
exports.getHardwareId = getHardwareId;
|
|
88
|
-
function requestInput(question) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
lineReader.question(question, resolve);
|
|
95
|
-
});
|
|
96
|
-
lineReader.close();
|
|
97
|
-
return answer.trim();
|
|
77
|
+
async function requestInput(question) {
|
|
78
|
+
const lineReader = (0, readline_1.createInterface)({
|
|
79
|
+
input: process.stdin,
|
|
80
|
+
output: process.stdout,
|
|
81
|
+
}), answer = await new Promise((resolve) => {
|
|
82
|
+
lineReader.question(question, resolve);
|
|
98
83
|
});
|
|
84
|
+
lineReader.close();
|
|
85
|
+
return answer.trim();
|
|
99
86
|
}
|
|
100
87
|
exports.requestInput = requestInput;
|
|
101
88
|
function stringify(data) {
|
|
@@ -123,6 +110,15 @@ function randomString(length) {
|
|
|
123
110
|
exports.randomString = randomString;
|
|
124
111
|
// Override push receiver logging to avoid ECONNRESET errors leaking
|
|
125
112
|
function logPushReceiver(...args) {
|
|
113
|
+
try {
|
|
114
|
+
if (args[0].toString().includes('ECONNRESET')) {
|
|
115
|
+
// don't log ECONNRESET errors
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (_) {
|
|
120
|
+
// proceed to log error
|
|
121
|
+
}
|
|
126
122
|
logDebug('[Push Receiver]');
|
|
127
123
|
logDebug(args[0]);
|
|
128
124
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ring-client-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"description": "Unofficial API for Ring doorbells, cameras, security alarm system and smart lighting",
|
|
5
5
|
"main": "lib/api/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -63,8 +63,6 @@
|
|
|
63
63
|
"colors": "^1.4.0",
|
|
64
64
|
"debug": "^4.3.4",
|
|
65
65
|
"got": "^11.8.3",
|
|
66
|
-
"homebridge-config-ui-x": "^4.43.3",
|
|
67
|
-
"homebridge-ring": "^9.24.0",
|
|
68
66
|
"rxjs": "^7.5.5",
|
|
69
67
|
"socket.io-client": "^2.4.0",
|
|
70
68
|
"systeminformation": "^5.11.14",
|
|
@@ -99,7 +97,7 @@
|
|
|
99
97
|
"typescript": "4.6.4"
|
|
100
98
|
},
|
|
101
99
|
"engines": {
|
|
102
|
-
"node": "^
|
|
100
|
+
"node": "^16",
|
|
103
101
|
"homebridge": ">=1.4.0"
|
|
104
102
|
},
|
|
105
103
|
"bugs": {
|