ring-client-api 10.0.0-beta.3 → 10.0.0-beta.6

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isWebSocketSupportedAsset = exports.disabledLocationModes = exports.DispatchSignalType = exports.DoorbellType = exports.ChimeModel = exports.deviceTypesWithVolume = exports.allAlarmStates = exports.RingCameraModel = exports.isBatteryCameraKind = exports.RingCameraKind = exports.RingDeviceCategory = exports.RingDeviceType = void 0;
3
+ exports.isWebSocketSupportedAsset = exports.disabledLocationModes = exports.DispatchSignalType = exports.PushNotificationAction = exports.NotificationDetectionType = exports.DoorbellType = exports.ChimeModel = exports.deviceTypesWithVolume = exports.allAlarmStates = exports.RingCameraModel = exports.RingCameraKind = exports.RingDeviceCategory = exports.RingDeviceType = void 0;
4
4
  // eslint-disable-next-line no-shadow
5
5
  var RingDeviceType;
6
6
  (function (RingDeviceType) {
@@ -95,12 +95,6 @@ var RingCameraKind;
95
95
  RingCameraKind["cocoa_doorbell"] = "cocoa_doorbell";
96
96
  RingCameraKind["stickup_cam_mini"] = "stickup_cam_mini";
97
97
  })(RingCameraKind = exports.RingCameraKind || (exports.RingCameraKind = {}));
98
- // RegExp taken from ring.com app
99
- const isWiredCameraRegExp = new RegExp(/(^(lpd|jbox|stickup_cam_elite|stickup_cam_mini|hp_cam|spotlightw|floodlight|doorbell_graham_cracker))/);
100
- function isBatteryCameraKind(kind) {
101
- return !kind.match(isWiredCameraRegExp);
102
- }
103
- exports.isBatteryCameraKind = isBatteryCameraKind;
104
98
  exports.RingCameraModel = {
105
99
  doorbot: 'Doorbell',
106
100
  doorbell: 'Doorbell',
@@ -158,6 +152,23 @@ var DoorbellType;
158
152
  DoorbellType[DoorbellType["None"] = 2] = "None";
159
153
  })(DoorbellType = exports.DoorbellType || (exports.DoorbellType = {}));
160
154
  // eslint-disable-next-line no-shadow
155
+ var NotificationDetectionType;
156
+ (function (NotificationDetectionType) {
157
+ // Note, this list may not be complete
158
+ NotificationDetectionType["Human"] = "human";
159
+ NotificationDetectionType["Loitering"] = "loitering";
160
+ NotificationDetectionType["Motion"] = "motion";
161
+ NotificationDetectionType["OtherMotion"] = "other_motion";
162
+ NotificationDetectionType["NotAvailable"] = "null";
163
+ NotificationDetectionType["StreamBroken"] = "stream_broken";
164
+ })(NotificationDetectionType = exports.NotificationDetectionType || (exports.NotificationDetectionType = {}));
165
+ // eslint-disable-next-line no-shadow
166
+ var PushNotificationAction;
167
+ (function (PushNotificationAction) {
168
+ PushNotificationAction["Ding"] = "com.ring.push.HANDLE_NEW_DING";
169
+ PushNotificationAction["Motion"] = "com.ring.push.HANDLE_NEW_motion";
170
+ })(PushNotificationAction = exports.PushNotificationAction || (exports.PushNotificationAction = {}));
171
+ // eslint-disable-next-line no-shadow
161
172
  var DispatchSignalType;
162
173
  (function (DispatchSignalType) {
163
174
  DispatchSignalType["Burglar"] = "user-verified-burglar-xa";
@@ -1,7 +1,24 @@
1
- import { MediaStreamTrack, RTCIceCandidate, RTCPeerConnection, RtcpPacket, RtpPacket } from '@koush/werift';
2
- import { ReplaySubject, Subject } from 'rxjs';
3
- export declare class PeerConnection {
4
- pc: RTCPeerConnection;
1
+ import { ConnectionState, MediaStreamTrack, RTCIceCandidate, RtcpPacket, RtpPacket } from '@koush/werift';
2
+ import { Observable, ReplaySubject, Subject } from 'rxjs';
3
+ export interface BasicPeerConnection {
4
+ createOffer(): Promise<{
5
+ sdp: string;
6
+ }>;
7
+ createAnswer(offer: {
8
+ type: 'offer';
9
+ sdp: string;
10
+ }): Promise<RTCSessionDescriptionInit>;
11
+ acceptAnswer(answer: {
12
+ type: 'answer';
13
+ sdp: string;
14
+ }): Promise<void>;
15
+ addIceCandidate(candidate: RTCIceCandidate): Promise<void>;
16
+ onIceCandidate: Observable<RTCIceCandidate>;
17
+ onConnectionState: Observable<ConnectionState>;
18
+ close(): void;
19
+ }
20
+ export declare class WeriftPeerConnection implements BasicPeerConnection {
21
+ private pc;
5
22
  onAudioRtp: Subject<RtpPacket>;
6
23
  onAudioRtcp: Subject<RtcpPacket>;
7
24
  onVideoRtp: Subject<RtpPacket>;
@@ -9,12 +9,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.PeerConnection = void 0;
12
+ exports.WeriftPeerConnection = void 0;
13
13
  const werift_1 = require("@koush/werift");
14
14
  const rxjs_1 = require("rxjs");
15
- const util_1 = require("./util");
16
- const debug = false;
17
- class PeerConnection {
15
+ const util_1 = require("../util");
16
+ const debug = false, ringIceServers = [
17
+ 'stun:stun.kinesisvideo.us-east-1.amazonaws.com:443',
18
+ 'stun:stun.kinesisvideo.us-east-2.amazonaws.com:443',
19
+ 'stun:stun.kinesisvideo.us-west-2.amazonaws.com:443',
20
+ 'stun:stun.l.google.com:19302',
21
+ 'stun:stun1.l.google.com:19302',
22
+ 'stun:stun2.l.google.com:19302',
23
+ 'stun:stun3.l.google.com:19302',
24
+ 'stun:stun4.l.google.com:19302',
25
+ ];
26
+ class WeriftPeerConnection {
18
27
  constructor() {
19
28
  this.onAudioRtp = new rxjs_1.Subject();
20
29
  this.onAudioRtcp = new rxjs_1.Subject();
@@ -43,10 +52,12 @@ class PeerConnection {
43
52
  { type: 'nack', parameter: 'pli' },
44
53
  { type: 'goog-remb' },
45
54
  ],
46
- parameters: 'packetization-mode=1;profile-level-id=42801F;level-asymmetry-allowed=1',
55
+ parameters: 'packetization-mode=1;profile-level-id=640029;level-asymmetry-allowed=1',
47
56
  }),
48
57
  ],
49
58
  },
59
+ iceServers: ringIceServers.map((server) => ({ urls: server })),
60
+ iceTransportPolicy: 'all',
50
61
  })), audioTransceiver = pc.addTransceiver(this.returnAudioTrack, {
51
62
  direction: 'sendrecv',
52
63
  }), videoTransceiver = pc.addTransceiver('video', {
@@ -120,4 +131,4 @@ class PeerConnection {
120
131
  this.pc.close().catch(util_1.logError);
121
132
  }
122
133
  }
123
- exports.PeerConnection = PeerConnection;
134
+ exports.WeriftPeerConnection = WeriftPeerConnection;
@@ -0,0 +1,65 @@
1
+ import { RingCamera } from '../ring-camera';
2
+ import { StreamingConnectionBase, StreamingConnectionOptions } from './streaming-connection-base';
3
+ interface SessionBody {
4
+ doorbot_id: number;
5
+ session_id: string;
6
+ }
7
+ interface AnswerMessage {
8
+ method: 'sdp';
9
+ body: {
10
+ sdp: string;
11
+ type: 'answer';
12
+ } & SessionBody;
13
+ }
14
+ interface IceCandidateMessage {
15
+ method: 'ice';
16
+ body: {
17
+ ice: string;
18
+ mlineindex: number;
19
+ } & SessionBody;
20
+ }
21
+ interface SessionCreatedMessage {
22
+ method: 'session_created';
23
+ body: SessionBody;
24
+ }
25
+ interface SessionStartedMessage {
26
+ method: 'session_started';
27
+ body: SessionBody;
28
+ }
29
+ interface PongMessage {
30
+ method: 'pong';
31
+ body: SessionBody;
32
+ }
33
+ interface NotificationMessage {
34
+ method: 'notification';
35
+ body: {
36
+ is_ok: boolean;
37
+ text: string;
38
+ } & SessionBody;
39
+ }
40
+ declare enum CloseReasonCode {
41
+ NormalClose = 0,
42
+ AuthenticationFailed = 5,
43
+ Timeout = 6
44
+ }
45
+ interface CloseMessage {
46
+ method: 'close';
47
+ body: {
48
+ reason: {
49
+ code: CloseReasonCode;
50
+ text: string;
51
+ };
52
+ } & SessionBody;
53
+ }
54
+ declare type IncomingMessage = AnswerMessage | IceCandidateMessage | SessionCreatedMessage | SessionStartedMessage | PongMessage | CloseMessage | NotificationMessage;
55
+ export declare class RingEdgeConnection extends StreamingConnectionBase {
56
+ private camera;
57
+ private readonly onSessionId;
58
+ private readonly onOfferSent;
59
+ constructor(authToken: string, camera: RingCamera, options: StreamingConnectionOptions);
60
+ private initiateCall;
61
+ private sessionId;
62
+ protected handleMessage(message: IncomingMessage): Promise<void>;
63
+ protected sendSessionMessage(method: string, body?: Record<any, any>): void;
64
+ }
65
+ export {};
@@ -0,0 +1,155 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RingEdgeConnection = void 0;
13
+ const ws_1 = require("ws");
14
+ const rxjs_1 = require("rxjs");
15
+ const util_1 = require("../util");
16
+ const operators_1 = require("rxjs/operators");
17
+ const streaming_connection_base_1 = require("./streaming-connection-base");
18
+ // eslint-disable-next-line no-shadow
19
+ var CloseReasonCode;
20
+ (function (CloseReasonCode) {
21
+ CloseReasonCode[CloseReasonCode["NormalClose"] = 0] = "NormalClose";
22
+ // reason: { code: 5, text: '[rsl-apps/webrtc-liveview-server/Session.cpp:429] [Auth] [0xd540]: [rsl-apps/session-manager/Manager.cpp:227] [AppAuth] Unauthorized: invalid or expired token' }
23
+ // reason: { code: 5, text: 'Authentication failed: -1' }
24
+ // reason: { code: 5, text: 'Sessions with the provided ID not found' }
25
+ CloseReasonCode[CloseReasonCode["AuthenticationFailed"] = 5] = "AuthenticationFailed";
26
+ // reason: { code: 6, text: 'Timeout waiting for ping' }
27
+ CloseReasonCode[CloseReasonCode["Timeout"] = 6] = "Timeout";
28
+ })(CloseReasonCode || (CloseReasonCode = {}));
29
+ class RingEdgeConnection extends streaming_connection_base_1.StreamingConnectionBase {
30
+ constructor(authToken, camera, options) {
31
+ super(new ws_1.WebSocket('wss://api.prod.signalling.ring.devices.a2z.com:443/ws', {
32
+ headers: {
33
+ Authorization: `Bearer ${authToken}`,
34
+ 'X-Sig-API-Version': '4.0',
35
+ 'X-Sig-Client-ID': 'ring_android-aabb123',
36
+ 'X-Sig-Client-Info': 'Ring/3.49.0;Platform/Android;OS/7.0;Density/2.0;Device/samsung-SM-T710;Locale/en-US;TimeZone/GMT-07:00',
37
+ 'X-Sig-Auth-Type': 'ring_oauth',
38
+ },
39
+ }), options);
40
+ this.camera = camera;
41
+ this.onSessionId = new rxjs_1.ReplaySubject(1);
42
+ this.onOfferSent = new rxjs_1.ReplaySubject(1);
43
+ this.sessionId = null;
44
+ this.addSubscriptions(this.onWsOpen.subscribe(() => {
45
+ (0, util_1.logDebug)(`WebSocket connected for ${camera.name} (Ring Edge)`);
46
+ this.initiateCall().catch((e) => {
47
+ (0, util_1.logError)(e);
48
+ this.callEnded();
49
+ });
50
+ }),
51
+ // The ring-edge session needs a ping every 5 seconds to keep the connection alive
52
+ this.onCallAnswered
53
+ .pipe((0, operators_1.switchMap)(() => (0, rxjs_1.interval)(5000)))
54
+ .subscribe(() => {
55
+ if (!this.sessionId) {
56
+ return;
57
+ }
58
+ this.sendSessionMessage('ping');
59
+ }), this.pc.onIceCandidate.subscribe((iceCandidate) => __awaiter(this, void 0, void 0, function* () {
60
+ yield (0, rxjs_1.firstValueFrom)(this.onOfferSent);
61
+ this.sendMessage({
62
+ method: 'ice',
63
+ body: {
64
+ doorbot_id: camera.id,
65
+ ice: iceCandidate.candidate,
66
+ mlineindex: 0,
67
+ },
68
+ });
69
+ // HACK: send ice candidate with both mline indexes to convince ring edge to connect both audio and video
70
+ // Without this, only audio will connect unless you connect from the network of the Ring Edge router
71
+ this.sendMessage({
72
+ method: 'ice',
73
+ body: {
74
+ doorbot_id: camera.id,
75
+ ice: iceCandidate.candidate,
76
+ mlineindex: 1,
77
+ },
78
+ });
79
+ })));
80
+ }
81
+ initiateCall() {
82
+ return __awaiter(this, void 0, void 0, function* () {
83
+ const { sdp } = yield this.pc.createOffer();
84
+ this.sendMessage({
85
+ method: 'live_view',
86
+ body: {
87
+ doorbot_id: this.camera.id,
88
+ stream_options: { audio_enabled: true, video_enabled: true },
89
+ sdp: sdp.replace('\na=group:BUNDLE 0 1', ''),
90
+ },
91
+ });
92
+ this.onOfferSent.next();
93
+ });
94
+ }
95
+ handleMessage(message) {
96
+ return __awaiter(this, void 0, void 0, function* () {
97
+ if (message.body.doorbot_id !== this.camera.id) {
98
+ // ignore messages for other cameras
99
+ return;
100
+ }
101
+ if (['session_created', 'session_started'].includes(message.method) &&
102
+ 'session_id' in message.body &&
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
109
+ return;
110
+ }
111
+ switch (message.method) {
112
+ case 'session_created':
113
+ case 'session_started':
114
+ // session already stored above
115
+ return;
116
+ case 'sdp':
117
+ yield this.pc.acceptAnswer(message.body);
118
+ this.onCallAnswered.next(message.body.sdp);
119
+ return;
120
+ case 'ice':
121
+ yield this.pc.addIceCandidate({
122
+ candidate: message.body.ice,
123
+ sdpMLineIndex: message.body.mlineindex,
124
+ });
125
+ return;
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
+ });
137
+ }
138
+ sendSessionMessage(method, body = {}) {
139
+ const message = {
140
+ method,
141
+ body: Object.assign(Object.assign({}, body), { doorbot_id: this.camera.id, session_id: this.sessionId }),
142
+ };
143
+ if (this.sessionId) {
144
+ // Send immediately if we already have a session id
145
+ // This is needed to send `close` before closing the websocket
146
+ this.sendMessage(message);
147
+ }
148
+ else {
149
+ (0, rxjs_1.firstValueFrom)(this.onSessionId)
150
+ .then(() => this.sendMessage(message))
151
+ .catch((e) => (0, util_1.logError)(e));
152
+ }
153
+ }
154
+ }
155
+ exports.RingEdgeConnection = RingEdgeConnection;
@@ -0,0 +1,30 @@
1
+ import { BasicPeerConnection } from './peer-connection';
2
+ import { Subscribed } from '../subscribed';
3
+ import { WebSocket } from 'ws';
4
+ import { RtpPacket } from '@koush/werift';
5
+ import { ReplaySubject, Subject } from 'rxjs';
6
+ export interface StreamingConnectionOptions {
7
+ createPeerConnection?: () => BasicPeerConnection;
8
+ }
9
+ export declare abstract class StreamingConnectionBase extends Subscribed {
10
+ protected ws: WebSocket;
11
+ protected options: StreamingConnectionOptions;
12
+ readonly onCallAnswered: ReplaySubject<string>;
13
+ readonly onCallEnded: ReplaySubject<void>;
14
+ readonly onWsOpen: import("rxjs").Observable<unknown>;
15
+ protected readonly pc: BasicPeerConnection;
16
+ readonly onAudioRtp: Subject<RtpPacket>;
17
+ readonly onVideoRtp: Subject<RtpPacket>;
18
+ constructor(ws: WebSocket, options?: StreamingConnectionOptions);
19
+ protected abstract handleMessage(message: {
20
+ method: string;
21
+ }): Promise<void>;
22
+ protected abstract sendSessionMessage(method: string, body?: Record<any, any>): void;
23
+ private activated;
24
+ activate(): Promise<void>;
25
+ activateCameraSpeaker(): Promise<void>;
26
+ protected sendMessage(message: Record<any, any>): void;
27
+ sendAudioPacket(rtp: RtpPacket): void;
28
+ protected callEnded(): void;
29
+ stop(): void;
30
+ }
@@ -0,0 +1,111 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.StreamingConnectionBase = void 0;
13
+ const peer_connection_1 = require("./peer-connection");
14
+ const subscribed_1 = require("../subscribed");
15
+ const rxjs_1 = require("rxjs");
16
+ const operators_1 = require("rxjs/operators");
17
+ const util_1 = require("../util");
18
+ class StreamingConnectionBase extends subscribed_1.Subscribed {
19
+ constructor(ws, options = {}) {
20
+ super();
21
+ this.ws = ws;
22
+ this.options = options;
23
+ this.onCallAnswered = new rxjs_1.ReplaySubject(1);
24
+ this.onCallEnded = new rxjs_1.ReplaySubject(1);
25
+ this.activated = false;
26
+ if (options.createPeerConnection) {
27
+ // we were passed a custom peer connection factory
28
+ this.pc = options.createPeerConnection();
29
+ // passing rtp packets is not supported for custom peer connections
30
+ this.onAudioRtp = new rxjs_1.Subject();
31
+ this.onVideoRtp = new rxjs_1.Subject();
32
+ }
33
+ else {
34
+ // no custom peer connection factory, use the werift and pass along rtp packets
35
+ const pc = new peer_connection_1.WeriftPeerConnection();
36
+ this.pc = pc;
37
+ this.onAudioRtp = pc.onAudioRtp;
38
+ this.onVideoRtp = pc.onVideoRtp;
39
+ }
40
+ this.onWsOpen = (0, rxjs_1.fromEvent)(this.ws, 'open');
41
+ const onMessage = (0, rxjs_1.fromEvent)(this.ws, 'message'), onError = (0, rxjs_1.fromEvent)(this.ws, 'error'), onClose = (0, rxjs_1.fromEvent)(this.ws, 'close');
42
+ this.addSubscriptions(onMessage
43
+ .pipe((0, operators_1.concatMap)((message) => {
44
+ return this.handleMessage(JSON.parse(message.data));
45
+ }))
46
+ .subscribe(), onError.subscribe((e) => {
47
+ (0, util_1.logError)(e);
48
+ this.callEnded();
49
+ }), onClose.subscribe(() => {
50
+ this.callEnded();
51
+ }), this.pc.onConnectionState.subscribe((state) => {
52
+ if (state === 'failed') {
53
+ (0, util_1.logError)('Stream connection failed');
54
+ this.callEnded();
55
+ }
56
+ if (state === 'closed') {
57
+ (0, util_1.logDebug)('Stream connection closed');
58
+ this.callEnded();
59
+ }
60
+ }));
61
+ }
62
+ activate() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ if (this.activated) {
65
+ return;
66
+ }
67
+ this.activated = true;
68
+ yield (0, rxjs_1.firstValueFrom)(this.pc.onConnectionState.pipe((0, operators_1.filter)((state) => state === 'connected')));
69
+ (0, util_1.logInfo)('Activating Session');
70
+ this.sendSessionMessage('activate_session');
71
+ });
72
+ }
73
+ activateCameraSpeaker() {
74
+ return __awaiter(this, void 0, void 0, function* () {
75
+ yield (0, rxjs_1.firstValueFrom)(this.onCallAnswered);
76
+ this.sendSessionMessage('camera_options', {
77
+ stealth_mode: false,
78
+ });
79
+ });
80
+ }
81
+ sendMessage(message) {
82
+ this.ws.send(JSON.stringify(message));
83
+ }
84
+ sendAudioPacket(rtp) {
85
+ if (this.pc instanceof peer_connection_1.WeriftPeerConnection) {
86
+ this.pc.returnAudioTrack.writeRtp(rtp);
87
+ }
88
+ else {
89
+ throw new Error('Cannot send audio packets to a custom peer connection implementation');
90
+ }
91
+ }
92
+ callEnded() {
93
+ try {
94
+ this.sendMessage({
95
+ reason: { code: 0, text: '' },
96
+ method: 'close',
97
+ });
98
+ this.ws.close();
99
+ }
100
+ catch (_) {
101
+ // ignore any errors since we are stopping the call
102
+ }
103
+ this.unsubscribe();
104
+ this.onCallEnded.next();
105
+ this.pc.close();
106
+ }
107
+ stop() {
108
+ this.callEnded();
109
+ }
110
+ }
111
+ exports.StreamingConnectionBase = StreamingConnectionBase;
@@ -1,7 +1,9 @@
1
- import { ReplaySubject } from 'rxjs';
2
- import { RingCamera } from './ring-camera';
3
- import { Subscribed } from './subscribed';
4
1
  import { RtpPacket } from '@koush/werift';
2
+ import { ReplaySubject, Subject } from 'rxjs';
3
+ import { RingEdgeConnection } from './ring-edge-connection';
4
+ import { WebrtcConnection } from './webrtc-connection';
5
+ import { RingCamera } from '../ring-camera';
6
+ import { Subscribed } from '../subscribed';
5
7
  declare type SpawnInput = string | number;
6
8
  export interface FfmpegOptions {
7
9
  input?: SpawnInput[];
@@ -9,27 +11,22 @@ export interface FfmpegOptions {
9
11
  audio?: SpawnInput[];
10
12
  output: SpawnInput[];
11
13
  }
12
- export declare class LiveCall extends Subscribed {
13
- private sessionId;
14
- private camera;
15
- private readonly ws;
16
- private readonly onWsOpen;
17
- private readonly onMessage;
18
- private readonly pc;
19
- readonly onCallAnswered: ReplaySubject<string>;
14
+ export declare class StreamingSession extends Subscribed {
15
+ private readonly camera;
16
+ private connection;
20
17
  readonly onCallEnded: ReplaySubject<void>;
18
+ readonly onVideoRtp: Subject<RtpPacket>;
19
+ readonly onAudioRtp: Subject<RtpPacket>;
21
20
  private readonly audioSplitter;
22
21
  private readonly videoSplitter;
23
- readonly onVideoRtp: import("rxjs").Subject<RtpPacket>;
24
- readonly onAudioRtp: import("rxjs").Subject<RtpPacket>;
25
- constructor(sessionId: string, camera: RingCamera);
26
- private handleMessage;
27
- reservePort(bufferPorts?: number): Promise<number>;
28
- startTranscoding(ffmpegOptions: FfmpegOptions): Promise<void>;
22
+ constructor(camera: RingCamera, connection: RingEdgeConnection | WebrtcConnection);
23
+ private bindToConnection;
29
24
  activated: boolean;
30
25
  activate(): Promise<void>;
26
+ cameraSpeakerActivated: boolean;
31
27
  activateCameraSpeaker(): Promise<void>;
32
- private sendMessage;
28
+ reservePort(bufferPorts?: number): Promise<number>;
29
+ startTranscoding(ffmpegOptions: FfmpegOptions): Promise<void>;
33
30
  private callEnded;
34
31
  stop(): void;
35
32
  sendAudioPacket(rtp: RtpPacket): void;