ringcentral-softphone 0.10.0 → 0.11.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/README.md CHANGED
@@ -4,7 +4,6 @@ This is a TypeScript SDK for RingCentral Softphone. It is a complete rewrite of
4
4
 
5
5
  Users are recommended to use this SDK instead of the JavaScript SDK.
6
6
 
7
-
8
7
  ## Installation
9
8
 
10
9
  ```
@@ -17,11 +16,10 @@ yarn install ringcentral-softphone
17
16
  2. Find the user/extension you want to use
18
17
  3. Check the user's "Devices & Numbers"
19
18
  4. Find a phone/device that you want to use
20
- 1. if there is none, you need to create one. Check steps below for more details
21
- 5. Click the "Set Up and Provision" button
22
- 6. Click the link "Set up manually using SIP"
23
- 7. At the bottom part of the page, you will find "User Name", "Password" and "Authorization ID"
24
-
19
+ 5. if there is none, you need to create one. Check steps below for more details
20
+ 6. Click the "Set Up and Provision" button
21
+ 7. Click the link "Set up manually using SIP"
22
+ 8. At the bottom part of the page, you will find "User Name", "Password" and "Authorization ID"
25
23
 
26
24
  ## Usage
27
25
 
@@ -38,12 +36,11 @@ const softphone = new Softphone({
38
36
 
39
37
  For complete examples, see [demos/](demos/)
40
38
 
41
-
42
39
  ## Supported features
43
40
 
44
41
  - inbound call
45
42
  - outbound call
46
- - inbound DTMF
43
+ - inbound DTMF
47
44
  - outbound DTMF
48
45
  - reject inbound call
49
46
  - cancel outbound call
@@ -71,7 +68,6 @@ Or
71
68
  play -b 8 -r 8000 -e mu-law test.raw
72
69
  ```
73
70
 
74
-
75
71
  ## Todo
76
72
 
77
73
  - Try other payload types, such as OPUS
@@ -82,7 +78,6 @@ play -b 8 -r 8000 -e mu-law test.raw
82
78
  - check the code of PJSIP and refactor the code.
83
79
  - Let developer check the call info, such as who is calling, who is being called, etc.
84
80
 
85
-
86
81
  ## Dev Notes
87
82
 
88
83
  - We don't need to explicitly tell remote server our local RTP port via SIP SDP message. We send a RTP message to the remote server first, so the remote server knows our IP and port. So, the port number in SDP message could be fake.
@@ -2,7 +2,7 @@ import fs from 'fs';
2
2
  import type { RtpPacket } from 'werift-rtp';
3
3
 
4
4
  import Softphone from '../src/softphone';
5
- import waitFor from 'wait-for-async';
5
+ // import waitFor from 'wait-for-async';
6
6
 
7
7
  const softphone = new Softphone({
8
8
  username: process.env.SIP_INFO_USERNAME,
@@ -33,9 +33,14 @@ const main = async () => {
33
33
  });
34
34
 
35
35
  // // send audio to remote peer
36
+ // await waitFor({ interval: 2000 });
36
37
  // const streamer = callSession.streamAudio(fs.readFileSync('demos/test.raw'));
37
38
  // await waitFor({ interval: 3000 });
38
- // // you may interrupt audio sending at any time
39
+ // // you may pause/resume/stop audio sending at any time
40
+ // streamer.pause();
41
+ // await waitFor({ interval: 3000 });
42
+ // streamer.resume();
43
+ // await waitFor({ interval: 2000 });
39
44
  // streamer.stop();
40
45
 
41
46
  // receive DTMF
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const fs_1 = __importDefault(require("fs"));
16
16
  const softphone_1 = __importDefault(require("../src/softphone"));
17
+ // import waitFor from 'wait-for-async';
17
18
  const softphone = new softphone_1.default({
18
19
  username: process.env.SIP_INFO_USERNAME,
19
20
  password: process.env.SIP_INFO_PASSWORD,
@@ -1 +1 @@
1
- {"version":3,"file":"inbound-call.js","sourceRoot":"","sources":["../../demos/inbound-call.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,4CAAoB;AAGpB,iEAAyC;AAGzC,MAAM,SAAS,GAAG,IAAI,mBAAS,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;CACvD,CAAC,CAAC;AACH,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,yBAAyB;AAEtD,MAAM,IAAI,GAAG,GAAS,EAAE;IACtB,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC3B,sBAAsB;IACtB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAO,aAAa,EAAE,EAAE;QAC7C,mBAAmB;QACnB,qCAAqC;QACrC,0CAA0C;QAE1C,kBAAkB;QAClB,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAE1D,gBAAgB;QAChB,MAAM,WAAW,GAAG,YAAE,CAAC,iBAAiB,CAAC,GAAG,WAAW,CAAC,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,SAAoB,EAAE,EAAE;YACrD,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,kCAAkC;QAClC,+EAA+E;QAC/E,qCAAqC;QACrC,iDAAiD;QACjD,mBAAmB;QAEnB,iCAAiC;QACjC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;YAChC,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,qCAAqC;QACrC,6BAA6B;QAC7B,qCAAqC;QACrC,6BAA6B;QAE7B,sBAAsB;QACtB,qCAAqC;QACrC,wBAAwB;QAExB,uBAAuB;QACvB,qCAAqC;QACrC,sEAAsE;IACxE,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAA,CAAC;AACF,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"inbound-call.js","sourceRoot":"","sources":["../../demos/inbound-call.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,4CAAoB;AAGpB,iEAAyC;AACzC,wCAAwC;AAExC,MAAM,SAAS,GAAG,IAAI,mBAAS,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;CACvD,CAAC,CAAC;AACH,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,yBAAyB;AAEtD,MAAM,IAAI,GAAG,GAAS,EAAE;IACtB,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC3B,sBAAsB;IACtB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAO,aAAa,EAAE,EAAE;QAC7C,mBAAmB;QACnB,qCAAqC;QACrC,0CAA0C;QAE1C,kBAAkB;QAClB,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAE1D,gBAAgB;QAChB,MAAM,WAAW,GAAG,YAAE,CAAC,iBAAiB,CAAC,GAAG,WAAW,CAAC,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,SAAoB,EAAE,EAAE;YACrD,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,kCAAkC;QAClC,+EAA+E;QAC/E,qCAAqC;QACrC,iDAAiD;QACjD,mBAAmB;QAEnB,iCAAiC;QACjC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;YAChC,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,qCAAqC;QACrC,6BAA6B;QAC7B,qCAAqC;QACrC,6BAA6B;QAE7B,sBAAsB;QACtB,qCAAqC;QACrC,wBAAwB;QAExB,uBAAuB;QACvB,qCAAqC;QACrC,sEAAsE;IACxE,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAA,CAAC;AACF,IAAI,EAAE,CAAC"}
@@ -38,9 +38,14 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
38
38
  writeStream.close();
39
39
  });
40
40
  // // send audio to remote peer
41
+ // await waitFor({ interval: 2000 });
41
42
  // const streamer = callSession.streamAudio(fs.readFileSync('demos/test.raw'));
42
43
  // await waitFor({ interval: 3000 });
43
- // // you may interrupt audio sending at any time
44
+ // // you may pause/resume/stop audio sending at any time
45
+ // streamer.pause();
46
+ // await waitFor({ interval: 3000 });
47
+ // streamer.resume();
48
+ // await waitFor({ interval: 2000 });
44
49
  // streamer.stop();
45
50
  // receive DTMF
46
51
  callSession.on('dtmf', (digit) => {
@@ -1 +1 @@
1
- {"version":3,"file":"outbound-call.js","sourceRoot":"","sources":["../../demos/outbound-call.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,4CAAoB;AAEpB,oEAAqC;AAErC,iEAAyC;AAEzC,MAAM,SAAS,GAAG,IAAI,mBAAS,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;CACvD,CAAC,CAAC;AACH,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,yBAAyB;AAEtD,MAAM,IAAI,GAAG,GAAS,EAAE;IACtB,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC3B,MAAM,IAAA,wBAAO,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,+FAA+F;IAC/F,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,IAAI,CACtC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAmB,EAAE,EAAE,CAAC,CAE9C,CAAC;IAEF,0BAA0B;IAC1B,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAS,EAAE;QACtC,gBAAgB;QAChB,MAAM,WAAW,GAAG,YAAE,CAAC,iBAAiB,CAAC,GAAG,WAAW,CAAC,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,SAAoB,EAAE,EAAE;YACrD,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,iCAAiC;QACjC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;YAChC,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,+EAA+E;QAC/E,qCAAqC;QACrC,iDAAiD;QACjD,mBAAmB;QAEnB,eAAe;QACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,qCAAqC;QACrC,6BAA6B;QAC7B,qCAAqC;QACrC,6BAA6B;QAE7B,sBAAsB;QACtB,qCAAqC;QACrC,wBAAwB;QAExB,uBAAuB;QACvB,qCAAqC;QACrC,sEAAsE;IACxE,CAAC,CAAA,CAAC,CAAC;IAEH,+CAA+C;IAC/C,qCAAqC;IACrC,wBAAwB;AAC1B,CAAC,CAAA,CAAC;AACF,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"outbound-call.js","sourceRoot":"","sources":["../../demos/outbound-call.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,4CAAoB;AAEpB,oEAAqC;AAErC,iEAAyC;AAEzC,MAAM,SAAS,GAAG,IAAI,mBAAS,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACvC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;CACvD,CAAC,CAAC;AACH,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,yBAAyB;AAEtD,MAAM,IAAI,GAAG,GAAS,EAAE;IACtB,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC3B,MAAM,IAAA,wBAAO,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,+FAA+F;IAC/F,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,IAAI,CACtC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAmB,EAAE,EAAE,CAAC,CAE9C,CAAC;IAEF,0BAA0B;IAC1B,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAS,EAAE;QACtC,gBAAgB;QAChB,MAAM,WAAW,GAAG,YAAE,CAAC,iBAAiB,CAAC,GAAG,WAAW,CAAC,MAAM,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,SAAoB,EAAE,EAAE;YACrD,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,iCAAiC;QACjC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;YAChC,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,qCAAqC;QACrC,+EAA+E;QAC/E,qCAAqC;QACrC,yDAAyD;QACzD,oBAAoB;QACpB,qCAAqC;QACrC,qBAAqB;QACrB,qCAAqC;QACrC,mBAAmB;QAEnB,eAAe;QACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,qCAAqC;QACrC,6BAA6B;QAC7B,qCAAqC;QACrC,6BAA6B;QAE7B,sBAAsB;QACtB,qCAAqC;QACrC,wBAAwB;QAExB,uBAAuB;QACvB,qCAAqC;QACrC,sEAAsE;IACxE,CAAC,CAAA,CAAC,CAAC;IAEH,+CAA+C;IAC/C,qCAAqC;IACrC,wBAAwB;AAC1B,CAAC,CAAA,CAAC;AACF,IAAI,EAAE,CAAC"}
@@ -5,6 +5,7 @@ import EventEmitter from 'events';
5
5
  import dgram from 'dgram';
6
6
  import { type InboundMessage } from '../sip-message';
7
7
  import type Softphone from '../softphone';
8
+ import Streamer from './streamer';
8
9
  declare abstract class CallSession extends EventEmitter {
9
10
  softphone: Softphone;
10
11
  sipMessage: InboundMessage;
@@ -20,9 +21,7 @@ declare abstract class CallSession extends EventEmitter {
20
21
  transfer(target: string): Promise<void>;
21
22
  hangup(): Promise<void>;
22
23
  sendDTMF(char: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '*' | '#'): Promise<void>;
23
- streamAudio(input: Buffer): {
24
- stop(): void;
25
- };
24
+ streamAudio(input: Buffer): Streamer;
26
25
  protected startLocalServices(): Promise<void>;
27
26
  private dispose;
28
27
  }
@@ -18,6 +18,7 @@ const werift_rtp_1 = require("werift-rtp");
18
18
  const sip_message_1 = require("../sip-message");
19
19
  const utils_1 = require("../utils");
20
20
  const dtmf_1 = __importDefault(require("../dtmf"));
21
+ const streamer_1 = __importDefault(require("./streamer"));
21
22
  class CallSession extends events_1.default {
22
23
  constructor(softphone, sipMessage) {
23
24
  super();
@@ -100,46 +101,8 @@ class CallSession extends events_1.default {
100
101
  // buffer is the content of a audio file, it is supposed to be PCMU/8000 encoded.
101
102
  // The audio should be playable by command: ffplay -autoexit -f mulaw -ar 8000 test.raw
102
103
  streamAudio(input) {
103
- let buffer = input;
104
- let sequenceNumber = (0, utils_1.randomInt)();
105
- let timestamp = (0, utils_1.randomInt)();
106
- const ssrc = (0, utils_1.randomInt)();
107
- const streamer = {
108
- stop() {
109
- buffer = Buffer.alloc(0);
110
- },
111
- };
112
- const sendPacket = () => {
113
- if (buffer.length >= 160) {
114
- const temp = buffer.subarray(0, 160);
115
- buffer = buffer.subarray(160);
116
- const rtpPacket = new werift_rtp_1.RtpPacket(new werift_rtp_1.RtpHeader({
117
- version: 2,
118
- padding: false,
119
- paddingSize: 0,
120
- extension: false,
121
- marker: false,
122
- payloadOffset: 12,
123
- payloadType: 0,
124
- sequenceNumber,
125
- timestamp,
126
- ssrc,
127
- csrcLength: 0,
128
- csrc: [],
129
- extensionProfile: 48862,
130
- extensionLength: undefined,
131
- extensions: [],
132
- }), temp);
133
- if (this.disposed) {
134
- return;
135
- }
136
- this.send(rtpPacket.serialize());
137
- sequenceNumber += 1;
138
- timestamp += 160; // inbound audio use this time interval, in my opinion, it should be 20
139
- setTimeout(() => sendPacket(), 20);
140
- }
141
- };
142
- sendPacket();
104
+ const streamer = new streamer_1.default(this, input);
105
+ streamer.start();
143
106
  return streamer;
144
107
  }
145
108
  startLocalServices() {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/call-session/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/call-session/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /// <reference types="node" />
2
+ import type CallSession from '.';
3
+ declare class Streamer {
4
+ private callSession;
5
+ private buffer;
6
+ private originalBuffer;
7
+ private paused;
8
+ private finished;
9
+ private sequenceNumber;
10
+ private timestamp;
11
+ private ssrc;
12
+ constructor(callSesstion: CallSession, buffer: Buffer);
13
+ start(): Promise<void>;
14
+ stop(): Promise<void>;
15
+ pause(): Promise<void>;
16
+ resume(): Promise<void>;
17
+ private sendPacket;
18
+ }
19
+ export default Streamer;
@@ -0,0 +1,78 @@
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
+ const werift_rtp_1 = require("werift-rtp");
13
+ const utils_1 = require("../utils");
14
+ class Streamer {
15
+ constructor(callSesstion, buffer) {
16
+ this.paused = false;
17
+ this.finished = false;
18
+ this.sequenceNumber = (0, utils_1.randomInt)();
19
+ this.timestamp = (0, utils_1.randomInt)();
20
+ this.ssrc = (0, utils_1.randomInt)();
21
+ this.callSession = callSesstion;
22
+ this.buffer = buffer;
23
+ this.originalBuffer = buffer;
24
+ }
25
+ start() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ this.finished = false;
28
+ this.buffer = this.originalBuffer;
29
+ this.paused = false;
30
+ this.sendPacket();
31
+ });
32
+ }
33
+ stop() {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ this.finished = true;
36
+ });
37
+ }
38
+ pause() {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ this.paused = true;
41
+ });
42
+ }
43
+ resume() {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ this.paused = false;
46
+ this.sendPacket();
47
+ });
48
+ }
49
+ sendPacket() {
50
+ if (!this.callSession.disposed && !this.finished && !this.paused && this.buffer.length >= 160) {
51
+ const temp = this.buffer.subarray(0, 160);
52
+ this.buffer = this.buffer.subarray(160);
53
+ const rtpPacket = new werift_rtp_1.RtpPacket(new werift_rtp_1.RtpHeader({
54
+ version: 2,
55
+ padding: false,
56
+ paddingSize: 0,
57
+ extension: false,
58
+ marker: false,
59
+ payloadOffset: 12,
60
+ payloadType: 0,
61
+ sequenceNumber: this.sequenceNumber,
62
+ timestamp: this.timestamp,
63
+ ssrc: this.ssrc,
64
+ csrcLength: 0,
65
+ csrc: [],
66
+ extensionProfile: 48862,
67
+ extensionLength: undefined,
68
+ extensions: [],
69
+ }), temp);
70
+ this.callSession.send(rtpPacket.serialize());
71
+ this.sequenceNumber += 1;
72
+ this.timestamp += 160; // inbound audio use this time interval, in my opinion, it should be 20
73
+ setTimeout(() => this.sendPacket(), 20);
74
+ }
75
+ }
76
+ }
77
+ exports.default = Streamer;
78
+ //# sourceMappingURL=streamer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamer.js","sourceRoot":"","sources":["../../../src/call-session/streamer.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,2CAAkD;AAGlD,oCAAqC;AAErC,MAAM,QAAQ;IAUZ,YAAmB,YAAyB,EAAE,MAAc;QANpD,WAAM,GAAG,KAAK,CAAC;QACf,aAAQ,GAAG,KAAK,CAAC;QACjB,mBAAc,GAAG,IAAA,iBAAS,GAAE,CAAC;QAC7B,cAAS,GAAG,IAAA,iBAAS,GAAE,CAAC;QACxB,SAAI,GAAG,IAAA,iBAAS,GAAE,CAAC;QAGzB,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;IAC/B,CAAC;IAEY,KAAK;;YAChB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC;YAClC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;KAAA;IAEY,IAAI;;YACf,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;KAAA;IAEY,KAAK;;YAChB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;KAAA;IAEY,MAAM;;YACjB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;KAAA;IAEO,UAAU;QAChB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAC9F,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,SAAS,GAAG,IAAI,sBAAS,CAC7B,IAAI,sBAAS,CAAC;gBACZ,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,KAAK;gBACb,aAAa,EAAE,EAAE;gBACjB,WAAW,EAAE,CAAC;gBACd,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU,EAAE,CAAC;gBACb,IAAI,EAAE,EAAE;gBACR,gBAAgB,EAAE,KAAK;gBACvB,eAAe,EAAE,SAAS;gBAC1B,UAAU,EAAE,EAAE;aACf,CAAC,EACF,IAAI,CACL,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;YAC7C,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,uEAAuE;YAC9F,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;CACF;AAED,kBAAe,QAAQ,CAAC"}
package/package.json CHANGED
@@ -1,35 +1,40 @@
1
1
  {
2
2
  "name": "ringcentral-softphone",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
+ "homepage": "https://github.com/ringcentral/ringcentral-softphone-ts",
4
5
  "license": "MIT",
5
6
  "main": "dist/src/softphone.js",
6
7
  "types": "dist/src/softphone.d.ts",
7
8
  "scripts": {
8
- "lint": "eslint --fix '**/*.{ts,tsx,js,jsx}' && prettier --write . && sort-package-json",
9
9
  "in": "rm -rf *.raw && tsx -r dotenv-override-true/config demos/inbound-call.ts",
10
+ "lint": "eslint --fix '**/*.{ts,tsx,js,jsx}' && prettier --write . && sort-package-json",
10
11
  "out": "rm -rf *.raw && tsx -r dotenv-override-true/config demos/outbound-call.ts",
11
12
  "prepublishOnly": "rm -rf *.raw && rm -rf dist && yarn tsc"
12
13
  },
13
- "homepage": "https://github.com/ringcentral/ringcentral-softphone-ts",
14
+ "dependencies": {
15
+ "@rc-ex/core": "^1.3.15",
16
+ "wait-for-async": "^0.6.1",
17
+ "werift-rtp": "^0.8.1"
18
+ },
14
19
  "devDependencies": {
15
- "@types/node": "^20.11.30",
16
- "@typescript-eslint/eslint-plugin": "^7.3.1",
17
- "@typescript-eslint/parser": "^7.3.1",
20
+ "@types/node": "^20.12.7",
21
+ "@typescript-eslint/eslint-plugin": "^7.7.1",
22
+ "@typescript-eslint/parser": "^7.7.1",
18
23
  "dotenv-override-true": "^6.2.2",
19
24
  "eslint": "^8.57.0",
20
25
  "eslint-config-alloy": "^5.1.2",
21
26
  "eslint-config-prettier": "^9.1.0",
22
27
  "eslint-plugin-prettier": "^5.1.3",
23
28
  "prettier": "^3.2.5",
24
- "sort-package-json": "^2.8.0",
25
- "tsx": "^4.7.1",
26
- "ttpt": "^0.8.7",
27
- "typescript": "^5.4.3",
29
+ "sort-package-json": "^2.10.0",
30
+ "tsx": "^4.7.3",
31
+ "ttpt": "^0.8.9",
32
+ "typescript": "^5.4.5",
28
33
  "yarn-upgrade-all": "^0.7.2"
29
34
  },
30
- "dependencies": {
31
- "@rc-ex/core": "^1.3.10",
32
- "wait-for-async": "^0.6.1",
33
- "werift-rtp": "^0.8.1"
35
+ "yarn-upgrade-all": {
36
+ "ignore": [
37
+ "eslint"
38
+ ]
34
39
  }
35
40
  }
@@ -6,6 +6,7 @@ import { RequestMessage, type InboundMessage, ResponseMessage } from '../sip-mes
6
6
  import type Softphone from '../softphone';
7
7
  import { branch, extractAddress, randomInt } from '../utils';
8
8
  import DTMF from '../dtmf';
9
+ import Streamer from './streamer';
9
10
 
10
11
  abstract class CallSession extends EventEmitter {
11
12
  public softphone: Softphone;
@@ -97,49 +98,8 @@ abstract class CallSession extends EventEmitter {
97
98
  // buffer is the content of a audio file, it is supposed to be PCMU/8000 encoded.
98
99
  // The audio should be playable by command: ffplay -autoexit -f mulaw -ar 8000 test.raw
99
100
  public streamAudio(input: Buffer) {
100
- let buffer = input;
101
- let sequenceNumber = randomInt();
102
- let timestamp = randomInt();
103
- const ssrc = randomInt();
104
- const streamer = {
105
- stop() {
106
- buffer = Buffer.alloc(0);
107
- },
108
- };
109
- const sendPacket = () => {
110
- if (buffer.length >= 160) {
111
- const temp = buffer.subarray(0, 160);
112
- buffer = buffer.subarray(160);
113
- const rtpPacket = new RtpPacket(
114
- new RtpHeader({
115
- version: 2,
116
- padding: false,
117
- paddingSize: 0,
118
- extension: false,
119
- marker: false,
120
- payloadOffset: 12,
121
- payloadType: 0,
122
- sequenceNumber,
123
- timestamp,
124
- ssrc,
125
- csrcLength: 0,
126
- csrc: [],
127
- extensionProfile: 48862,
128
- extensionLength: undefined,
129
- extensions: [],
130
- }),
131
- temp,
132
- );
133
- if (this.disposed) {
134
- return;
135
- }
136
- this.send(rtpPacket.serialize());
137
- sequenceNumber += 1;
138
- timestamp += 160; // inbound audio use this time interval, in my opinion, it should be 20
139
- setTimeout(() => sendPacket(), 20);
140
- }
141
- };
142
- sendPacket();
101
+ const streamer = new Streamer(this, input);
102
+ streamer.start();
143
103
  return streamer;
144
104
  }
145
105
 
@@ -0,0 +1,74 @@
1
+ import { RtpHeader, RtpPacket } from 'werift-rtp';
2
+
3
+ import type CallSession from '.';
4
+ import { randomInt } from '../utils';
5
+
6
+ class Streamer {
7
+ private callSession: CallSession;
8
+ private buffer: Buffer;
9
+ private originalBuffer: Buffer;
10
+ private paused = false;
11
+ private finished = false;
12
+ private sequenceNumber = randomInt();
13
+ private timestamp = randomInt();
14
+ private ssrc = randomInt();
15
+
16
+ public constructor(callSesstion: CallSession, buffer: Buffer) {
17
+ this.callSession = callSesstion;
18
+ this.buffer = buffer;
19
+ this.originalBuffer = buffer;
20
+ }
21
+
22
+ public async start() {
23
+ this.finished = false;
24
+ this.buffer = this.originalBuffer;
25
+ this.paused = false;
26
+ this.sendPacket();
27
+ }
28
+
29
+ public async stop() {
30
+ this.finished = true;
31
+ }
32
+
33
+ public async pause() {
34
+ this.paused = true;
35
+ }
36
+
37
+ public async resume() {
38
+ this.paused = false;
39
+ this.sendPacket();
40
+ }
41
+
42
+ private sendPacket() {
43
+ if (!this.callSession.disposed && !this.finished && !this.paused && this.buffer.length >= 160) {
44
+ const temp = this.buffer.subarray(0, 160);
45
+ this.buffer = this.buffer.subarray(160);
46
+ const rtpPacket = new RtpPacket(
47
+ new RtpHeader({
48
+ version: 2,
49
+ padding: false,
50
+ paddingSize: 0,
51
+ extension: false,
52
+ marker: false,
53
+ payloadOffset: 12,
54
+ payloadType: 0,
55
+ sequenceNumber: this.sequenceNumber,
56
+ timestamp: this.timestamp,
57
+ ssrc: this.ssrc,
58
+ csrcLength: 0,
59
+ csrc: [],
60
+ extensionProfile: 48862,
61
+ extensionLength: undefined,
62
+ extensions: [],
63
+ }),
64
+ temp,
65
+ );
66
+ this.callSession.send(rtpPacket.serialize());
67
+ this.sequenceNumber += 1;
68
+ this.timestamp += 160; // inbound audio use this time interval, in my opinion, it should be 20
69
+ setTimeout(() => this.sendPacket(), 20);
70
+ }
71
+ }
72
+ }
73
+
74
+ export default Streamer;
package/tsconfig.json CHANGED
@@ -7,4 +7,4 @@
7
7
  "module": "commonjs",
8
8
  "target": "ES2015"
9
9
  }
10
- }
10
+ }