Преглед на файлове

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.
master
virtuacoplenny преди 5 години
родител
ревизия
4d38d24fa9
No account linked to committer's email address
променени са 1 файла, в които са добавени 54 реда и са изтрити 0 реда
  1. 54
    0
      modules/RTC/TraceablePeerConnection.js

+ 54
- 0
modules/RTC/TraceablePeerConnection.js Целия файл

@@ -93,6 +93,24 @@ export default function TraceablePeerConnection(
93 93
      */
94 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 115
      * Indicates whether or not this peer connection instance is actively
98 116
      * sending/receiving video media. When set to <tt>false</tt> the SDP video
@@ -2141,15 +2159,48 @@ TraceablePeerConnection.prototype.sendTones = function(tones, duration = 200, in
2141 2159
             }
2142 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 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 2179
         this._dtmfSender.insertDTMF(tones, duration, interToneGap);
2148 2180
     } else {
2149 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 2205
  * Makes the underlying TraceablePeerConnection generate new SSRC for
2155 2206
  * the recvonly video stream.
@@ -2193,6 +2244,9 @@ TraceablePeerConnection.prototype.close = function() {
2193 2244
 
2194 2245
     this._addedStreams = [];
2195 2246
 
2247
+    this._dtmfSender = null;
2248
+    this._dtmfTonesQueue = [];
2249
+
2196 2250
     if (!this.rtc._removePeerConnection(this)) {
2197 2251
         logger.error('RTC._removePeerConnection returned false');
2198 2252
     }

Loading…
Отказ
Запис