diff --git a/lib/call-session.js b/lib/call-session.js index 3bdd02d..0c928bf 100644 --- a/lib/call-session.js +++ b/lib/call-session.js @@ -64,6 +64,7 @@ class CallSession extends Emitter { this.application_sid = req.locals.application_sid; this.account_sid = req.locals.account_sid; this.service_provider_sid = req.locals.service_provider_sid; + this.srsClients = []; } get isFromMSTeams() { @@ -317,10 +318,7 @@ class CallSession extends Emitter { this.activeCallIds.delete(callId); if (dlg.other && dlg.other.connected) dlg.other.destroy().catch((e) => {}); - if (this.srsClient) { - this.srsClient.stop(); - this.srsClient = null; - } + this._stopRecording(); this.srf.endSession(this.req); }); @@ -329,6 +327,13 @@ class CallSession extends Emitter { dlg.on('modify', this._onReinvite.bind(this, dlg)); } + _stopRecording() { + if (this.srsClients.length) { + this.srsClients.forEach((c) => c.stop()); + this.srsClients = []; + } + } + _setHandlers({uas, uac}) { this.emit('connected'); const callStart = Date.now(); @@ -412,10 +417,7 @@ class CallSession extends Emitter { dlg.other = null; other.other = null; - if (this.srsClient) { - this.srsClient.stop(); - this.srsClient = null; - } + this._stopRecording(); this.logger.info(`call ended with normal termination, there are ${this.activeCallIds.size} active`); this.srf.endSession(this.req); @@ -696,7 +698,7 @@ Duration=${payload.duration} ` const callSid = req.get('X-Call-Sid'); const accountSid = req.get('X-Account-Sid'); const applicationSid = req.get('X-Application-Sid'); - if (this.srsClient) { + if (this.srsClients.length) { res.send(400); this.logger.info('discarding duplicate startCallRecording request for a call'); return; @@ -706,13 +708,14 @@ Duration=${payload.duration} ` res.send(400); return; } - this.srsClient = new SrsClient(this.logger, { + const arr = srsUrl.split(','); + this.srsClients = arr.map((url) => new SrsClient(this.logger, { srf: dlg.srf, direction: 'inbound', originalInvite: this.req, callingNumber: this.req.callingNumber, calledNumber: this.req.calledNumber, - srsUrl, + srsUrl: url, srsRecordingId, callSid, accountSid, @@ -728,41 +731,49 @@ Duration=${payload.duration} ` blockMedia: this.blockMedia, unblockMedia: this.unblockMedia, unsubscribe: this.unsubscribe - }); + })); try { - succeeded = await this.srsClient.start(); + succeeded = (await Promise.all( + this.srsClients.map((c) => c.start()) + )).every((r) => r); } catch (err) { this.logger.error({err}, 'Error starting SipRec call recording'); } } else if (reason === 'stopCallRecording') { - if (!this.srsClient) { + if (!this.srsClients.length) { res.send(400); this.logger.info('discarding stopCallRecording request because we are not recording'); return; } try { - succeeded = await this.srsClient.stop(); + succeeded = (await Promise.all( + this.srsClients.map((c) => c.stop()) + )).every((r) => r); } catch (err) { this.logger.error({err}, 'Error stopping SipRec call recording'); } - this.srsClient = null; + this.srsClients = []; } else if (reason === 'pauseCallRecording') { - if (!this.srsClient || this.srsClient.paused) { + if (!this.srsClients.length || this.srsClients.every((c) => c.paused)) { this.logger.info('discarding invalid pauseCallRecording request'); res.send(400); return; } - succeeded = await this.srsClient.pause(); + succeeded = (await Promise.all( + this.srsClients.map((c) => c.pause()) + )).every((r) => r); } else if (reason === 'resumeCallRecording') { - if (!this.srsClient || !this.srsClient.paused) { + if (!this.srsClients.length || !this.srsClients.every((c) => c.paused)) { res.send(400); this.logger.info('discarding invalid resumeCallRecording request'); return; } - succeeded = await this.srsClient.resume(); + succeeded = (await Promise.all( + this.srsClients.map((c) => c.resume()) + )).every((r) => r); } res.send(succeeded ? 200 : 503); } @@ -815,8 +826,8 @@ Duration=${payload.duration} ` res.send(response.status, {headers: responseHeaders, body: response.body}); } } catch (err) { - if (this.srsClient) { - this.srsClient = null; + if (this.srsClients.length) { + this.srsClients = []; } res.send(500); this.logger.info({err}, `Error handing INFO request on ${dlg.type} leg`);