Browse Source

fix(dtmf): enqueue tones to be played (#994)

Calls to insertDTMF will stop any tone
playing in progress. Prevent such by
checking the tonebuffer for any tones
in play and queue tone playing if
any tones are in play.
dev1
virtuacoplenny 6 years ago
parent
commit
4d38d24fa9
No account linked to committer's email address
1 changed files with 54 additions and 0 deletions
  1. 54
    0
      modules/RTC/TraceablePeerConnection.js

+ 54
- 0
modules/RTC/TraceablePeerConnection.js View File

93
      */
93
      */
94
     this._dtmfSender = undefined;
94
     this._dtmfSender = undefined;
95
 
95
 
96
+    /**
97
+     * @typedef {Object} TouchToneRequest
98
+     * @property {string} tones - The DTMF tones string as defined by
99
+     * {@code RTCDTMFSender.insertDTMF}, 'tones' argument.
100
+     * @property {number} duration - The amount of time in milliseconds that
101
+     * each DTMF should last.
102
+     * @property {string} interToneGap - The length of time in miliseconds to
103
+     * wait between tones.
104
+     */
105
+    /**
106
+     * TouchToneRequests which are waiting to be played. This queue is filled
107
+     * if there are touch tones currently being played.
108
+     *
109
+     * @type {Array<TouchToneRequest>}
110
+     * @private
111
+     */
112
+    this._dtmfTonesQueue = [];
113
+
96
     /**
114
     /**
97
      * Indicates whether or not this peer connection instance is actively
115
      * Indicates whether or not this peer connection instance is actively
98
      * sending/receiving video media. When set to <tt>false</tt> the SDP video
116
      * sending/receiving video media. When set to <tt>false</tt> the SDP video
2141
             }
2159
             }
2142
             this._dtmfSender && logger.info(`${this} initialized DTMFSender using deprecated createDTMFSender`);
2160
             this._dtmfSender && logger.info(`${this} initialized DTMFSender using deprecated createDTMFSender`);
2143
         }
2161
         }
2162
+
2163
+        if (this._dtmfSender) {
2164
+            this._dtmfSender.ontonechange = this._onToneChange.bind(this);
2165
+        }
2144
     }
2166
     }
2145
 
2167
 
2146
     if (this._dtmfSender) {
2168
     if (this._dtmfSender) {
2169
+        if (this._dtmfSender.toneBuffer) {
2170
+            this._dtmfTonesQueue.push({
2171
+                tones,
2172
+                duration,
2173
+                interToneGap
2174
+            });
2175
+
2176
+            return;
2177
+        }
2178
+
2147
         this._dtmfSender.insertDTMF(tones, duration, interToneGap);
2179
         this._dtmfSender.insertDTMF(tones, duration, interToneGap);
2148
     } else {
2180
     } else {
2149
         logger.warn(`${this} sendTones - failed to select DTMFSender`);
2181
         logger.warn(`${this} sendTones - failed to select DTMFSender`);
2150
     }
2182
     }
2151
 };
2183
 };
2152
 
2184
 
2185
+/**
2186
+ * Callback ivoked by {@code this._dtmfSender} when it has finished playing
2187
+ * a single tone.
2188
+ *
2189
+ * @param {Object} event - The tonechange event which indicates what characters
2190
+ * are left to be played for the current tone.
2191
+ * @private
2192
+ * @returns {void}
2193
+ */
2194
+TraceablePeerConnection.prototype._onToneChange = function(event) {
2195
+    // An empty event.tone indicates the current tones have finished playing.
2196
+    // Automatically start playing any queued tones on finish.
2197
+    if (this._dtmfSender && event.tone === '' && this._dtmfTonesQueue.length) {
2198
+        const { tones, duration, interToneGap } = this._dtmfTonesQueue.shift();
2199
+
2200
+        this._dtmfSender.insertDTMF(tones, duration, interToneGap);
2201
+    }
2202
+};
2203
+
2153
 /**
2204
 /**
2154
  * Makes the underlying TraceablePeerConnection generate new SSRC for
2205
  * Makes the underlying TraceablePeerConnection generate new SSRC for
2155
  * the recvonly video stream.
2206
  * the recvonly video stream.
2193
 
2244
 
2194
     this._addedStreams = [];
2245
     this._addedStreams = [];
2195
 
2246
 
2247
+    this._dtmfSender = null;
2248
+    this._dtmfTonesQueue = [];
2249
+
2196
     if (!this.rtc._removePeerConnection(this)) {
2250
     if (!this.rtc._removePeerConnection(this)) {
2197
         logger.error('RTC._removePeerConnection returned false');
2251
         logger.error('RTC._removePeerConnection returned false');
2198
     }
2252
     }

Loading…
Cancel
Save