You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: speech-to-text/timing-stream.js
+61-46Lines changed: 61 additions & 46 deletions
Original file line number
Diff line number
Diff line change
@@ -1,53 +1,61 @@
1
1
'use strict';
2
2
3
-
varTransform=require('stream').Transform;
3
+
varDuplex=require('stream').Duplex;
4
4
varutil=require('util');
5
5
varclone=require('clone');
6
6
7
7
/**
8
-
* Applies some basic formating to transcriptions:
9
-
* - Capitalize the first word of each sentence
10
-
* - Add a period to the end
11
-
* - Fix any "cruft" in the transcription
12
-
* - etc.
8
+
* Slows results down to no faster than real time.
13
9
*
14
-
* @param opts
15
-
* @param opts.model - some models / languages need special handling
16
-
* @param [opts.hesitation='\u2026'] - what to put down for a "hesitation" event, defaults to an ellipsis (...)
10
+
* Useful when running recognizeBlob because the text can otherwise appear before the words are spoken
11
+
*
12
+
* @param {Object} opts
13
+
* @param {*} [opts.emitAtt=TimingStream.START] - set to TimingStream.END to only emit text that has been completely spoken.
14
+
* @param {Number} [opts.delay=0] - Additional delay (in seconds) to apply before emitting words, useful for precise syncing to audio tracks. May be negative
17
15
* @constructor
18
16
*/
19
17
functionTimingStream(opts){
20
18
this.opts=util._extend({
21
-
emitAt: TimingStream.WORD_START// WORD_START = emit the word as it's beginning to be spoken, WORD_END = once it's completely spoken
19
+
emitAt: TimingStream.START,
20
+
delay: 0,
21
+
allowHalfOpen: true// keep the readable side open after the source closes
returnthis.nextTick=setTimeout(this.tick.bind(this),0);// in case we are multiple results behind - don't schedule until we are out of final results that are due now
155
141
}
156
142
}
157
143
144
+
this.scheduleNextTick(cutoff);
145
+
};
146
+
147
+
/**
148
+
* Schedules next tick if possible.
149
+
*
150
+
* triggers the 'close' and 'end' events if the buffer is empty and no further results are expected
thrownewError('No future words found');// this shouldn't happen ever - getCurrentResult should automatically delete the result from the buffer if all of it's words are consumed
168
+
}else{
169
+
// if we have no next result in the buffer, and the source has ended, then we're done.
170
+
if(this.sourceEnded){
171
+
this.emit('close');
172
+
this.push(null);
173
+
}
174
+
}
158
175
};
159
176
160
177
functionnoTimestamps(result){
@@ -189,9 +206,7 @@ TimingStream.prototype.handleResult = function handleResult(result) {
189
206
this.interim.push(result);
190
207
}
191
208
192
-
if(!this.nextTick){
193
-
this.tick();
194
-
}
209
+
this.tick();
195
210
};
196
211
197
212
TimingStream.prototype.stop=function(){};// usually overwritten during the `pipe` event
0 commit comments