@lls/lls-audio 0.0.71 → 0.0.73
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/package.json +1 -1
- package/recorder/AudioWorker.js +118 -108
- package/recorder/Visualizer.js +22 -10
- package/recorder/index.js +23 -19
- package/stories/visualizer.js +7 -0
- package/stories/wordDetector.js +5 -6
- package/wordDetector/index.js +28 -43
package/package.json
CHANGED
package/recorder/AudioWorker.js
CHANGED
|
@@ -5,126 +5,136 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
var AudioWorker = function AudioWorker(self) {
|
|
7
7
|
var recLength = 0;
|
|
8
|
+
var buffersToProcess = [];
|
|
8
9
|
var recBuffers = [];
|
|
9
10
|
var audioBlob = null;
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
recLength += inputBuffer[0].length;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
function interleave(inputL, inputR) {
|
|
31
|
-
var length = inputL.length + inputR.length;
|
|
32
|
-
var result = new Float32Array(length);
|
|
33
|
-
|
|
34
|
-
var index = 0;
|
|
35
|
-
var inputIndex = 0;
|
|
36
|
-
|
|
37
|
-
while (index < length) {
|
|
38
|
-
result[index++] = inputL[inputIndex];
|
|
39
|
-
result[index++] = inputR[inputIndex];
|
|
40
|
-
inputIndex++;
|
|
41
|
-
}
|
|
42
|
-
return result;
|
|
12
|
+
var processBuffers = function processBuffers() {
|
|
13
|
+
buffersToProcess.forEach(function (_ref) {
|
|
14
|
+
var timestamp = _ref.timestamp,
|
|
15
|
+
inputBuffer = _ref.inputBuffer;
|
|
16
|
+
|
|
17
|
+
appendBuffer(timestamp, inputBuffer);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
var mergeBuffers = function mergeBuffers(recBuffers, recLength) {
|
|
22
|
+
var result = new Float32Array(recLength);
|
|
23
|
+
var offset = 0;
|
|
24
|
+
for (var i = 0; i < recBuffers.length; i++) {
|
|
25
|
+
result.set(recBuffers[i], offset);
|
|
26
|
+
offset += recBuffers[i].length;
|
|
43
27
|
}
|
|
28
|
+
return result;
|
|
29
|
+
};
|
|
44
30
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
var
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
view.setUint16(20, 1, true);
|
|
74
|
-
/* channel count */
|
|
75
|
-
view.setUint16(22, recBuffers.length, true);
|
|
76
|
-
/* sample rate */
|
|
77
|
-
view.setUint32(24, 44100, true);
|
|
78
|
-
/* byte rate (sample rate * block align) */
|
|
79
|
-
view.setUint32(28, 44100 * recBuffers.length * 2, true);
|
|
80
|
-
/* block align (channel count * bytes per sample) */
|
|
81
|
-
view.setUint16(32, recBuffers.length * 2, true);
|
|
82
|
-
/* bits per sample */
|
|
83
|
-
view.setUint16(34, 16, true);
|
|
84
|
-
/* data chunk identifier */
|
|
85
|
-
writeString(view, 36, 'data');
|
|
86
|
-
/* data chunk length */
|
|
87
|
-
view.setUint32(40, samples.length * 2, true);
|
|
88
|
-
|
|
89
|
-
floatTo16BitPCM(view, 44, samples);
|
|
90
|
-
|
|
91
|
-
return view;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
var exportWAV = function exportWAV(beginning, end) {
|
|
95
|
-
var buffers = [];
|
|
96
|
-
for (var channel = 0; channel < recBuffers.length; channel++) {
|
|
97
|
-
var length = 0;
|
|
98
|
-
var filtredRecBuffers = recBuffers[channel].filter(function (buffer) {
|
|
99
|
-
return buffer.timestamp >= beginning - 1000 && buffer.timestamp <= end;
|
|
100
|
-
}).map(function (buffer) {
|
|
101
|
-
length += buffer.length;
|
|
102
|
-
return buffer.data;
|
|
103
|
-
});
|
|
104
|
-
buffers.push(mergeBuffers(filtredRecBuffers, length));
|
|
105
|
-
}
|
|
106
|
-
var interleaved = recBuffers.length === 2 ? interleave(buffers[0], buffers[1]) : buffers[0];
|
|
107
|
-
var dataview = encodeWAV(interleaved);
|
|
108
|
-
audioBlob = new Blob([dataview], { type: 'audio/wav' });
|
|
109
|
-
};
|
|
31
|
+
var appendBuffer = function appendBuffer(timestamp, inputBuffer) {
|
|
32
|
+
for (var channel = 0; channel < inputBuffer.length; channel++) {
|
|
33
|
+
if (!recBuffers[channel]) recBuffers[channel] = [];
|
|
34
|
+
recBuffers[channel].push({ timestamp: timestamp, data: inputBuffer[channel], length: inputBuffer[channel].length });
|
|
35
|
+
}
|
|
36
|
+
recLength += inputBuffer[0].length;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
var interleave = function interleave(inputL, inputR) {
|
|
40
|
+
var length = inputL.length + inputR.length;
|
|
41
|
+
var result = new Float32Array(length);
|
|
42
|
+
|
|
43
|
+
var index = 0;
|
|
44
|
+
var inputIndex = 0;
|
|
45
|
+
|
|
46
|
+
while (index < length) {
|
|
47
|
+
result[index++] = inputL[inputIndex];
|
|
48
|
+
result[index++] = inputR[inputIndex];
|
|
49
|
+
inputIndex++;
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var writeString = function writeString(view, offset, string) {
|
|
55
|
+
for (var i = 0; i < string.length; i++) {
|
|
56
|
+
view.setUint8(offset + i, string.charCodeAt(i));
|
|
57
|
+
}
|
|
58
|
+
};
|
|
110
59
|
|
|
60
|
+
var floatTo16BitPCM = function floatTo16BitPCM(output, offset, input) {
|
|
61
|
+
for (var i = 0; i < input.length; i++, offset += 2) {
|
|
62
|
+
var s = Math.max(-1, Math.min(1, input[i]));
|
|
63
|
+
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
var encodeWAV = function encodeWAV(samples) {
|
|
68
|
+
var buffer = new ArrayBuffer(44 + samples.length * 2);
|
|
69
|
+
var view = new DataView(buffer);
|
|
70
|
+
|
|
71
|
+
/* RIFF identifier */
|
|
72
|
+
writeString(view, 0, 'RIFF');
|
|
73
|
+
/* RIFF chunk length */
|
|
74
|
+
view.setUint32(4, 36 + samples.length * 2, true);
|
|
75
|
+
/* RIFF type */
|
|
76
|
+
writeString(view, 8, 'WAVE');
|
|
77
|
+
/* format chunk identifier */
|
|
78
|
+
writeString(view, 12, 'fmt ');
|
|
79
|
+
/* format chunk length */
|
|
80
|
+
view.setUint32(16, 16, true);
|
|
81
|
+
/* sample format (raw) */
|
|
82
|
+
view.setUint16(20, 1, true);
|
|
83
|
+
/* channel count */
|
|
84
|
+
view.setUint16(22, recBuffers.length, true);
|
|
85
|
+
/* sample rate */
|
|
86
|
+
view.setUint32(24, 44100, true);
|
|
87
|
+
/* byte rate (sample rate * block align) */
|
|
88
|
+
view.setUint32(28, 44100 * recBuffers.length * 2, true);
|
|
89
|
+
/* block align (channel count * bytes per sample) */
|
|
90
|
+
view.setUint16(32, recBuffers.length * 2, true);
|
|
91
|
+
/* bits per sample */
|
|
92
|
+
view.setUint16(34, 16, true);
|
|
93
|
+
/* data chunk identifier */
|
|
94
|
+
writeString(view, 36, 'data');
|
|
95
|
+
/* data chunk length */
|
|
96
|
+
view.setUint32(40, samples.length * 2, true);
|
|
97
|
+
|
|
98
|
+
floatTo16BitPCM(view, 44, samples);
|
|
99
|
+
|
|
100
|
+
return view;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
var exportWAV = function exportWAV(beginning, end) {
|
|
104
|
+
processBuffers(); // append all buffers together
|
|
105
|
+
|
|
106
|
+
var buffers = [];
|
|
107
|
+
for (var channel = 0; channel < recBuffers.length; channel++) {
|
|
108
|
+
var length = 0;
|
|
109
|
+
var filtredRecBuffers = recBuffers[channel].filter(function (buffer) {
|
|
110
|
+
return buffer.timestamp >= beginning - 1000 && buffer.timestamp <= end;
|
|
111
|
+
}).map(function (buffer) {
|
|
112
|
+
length += buffer.length;
|
|
113
|
+
return buffer.data;
|
|
114
|
+
});
|
|
115
|
+
buffers.push(mergeBuffers(filtredRecBuffers, length));
|
|
116
|
+
}
|
|
117
|
+
var interleaved = recBuffers.length === 2 ? interleave(buffers[0], buffers[1]) : buffers[0];
|
|
118
|
+
var dataview = encodeWAV(interleaved);
|
|
119
|
+
return new Blob([dataview], { type: 'audio/wav' });
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
self.onmessage = function (e) {
|
|
111
123
|
switch (e.data.command) {
|
|
112
124
|
case 'append':
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
postMessage({ command: 'send_buffers', buffers: recBuffers });
|
|
125
|
+
buffersToProcess.push({
|
|
126
|
+
timestamp: e.data.timestamp,
|
|
127
|
+
inputBuffer: e.data.inputBuffer
|
|
128
|
+
});
|
|
119
129
|
break;
|
|
120
130
|
case 'exportWAV':
|
|
121
|
-
exportWAV(e.data.beginning, e.data.end);
|
|
122
|
-
postMessage({ command: 'send_WAV', audioBlob:
|
|
123
|
-
|
|
124
|
-
|
|
131
|
+
var _audioBlob = exportWAV(e.data.beginning, e.data.end);
|
|
132
|
+
postMessage({ command: 'send_WAV', audioBlob: _audioBlob });
|
|
133
|
+
|
|
134
|
+
// Clean variables
|
|
125
135
|
recLength = 0;
|
|
126
136
|
recBuffers = [];
|
|
127
|
-
|
|
137
|
+
buffersToProcess = [];
|
|
128
138
|
break;
|
|
129
139
|
}
|
|
130
140
|
};
|
package/recorder/Visualizer.js
CHANGED
|
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
|
|
7
|
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
8
|
+
|
|
7
9
|
var _react = require('react');
|
|
8
10
|
|
|
9
11
|
var _react2 = _interopRequireDefault(_react);
|
|
@@ -13,20 +15,30 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
13
15
|
var Circle = function Circle(_ref) {
|
|
14
16
|
var radius = _ref.radius,
|
|
15
17
|
maxRadius = _ref.maxRadius,
|
|
16
|
-
|
|
17
|
-
return _react2.default.createElement('circle', { r: radius
|
|
18
|
+
style = _ref.style;
|
|
19
|
+
return _react2.default.createElement('circle', { r: radius / maxRadius, style: _extends({ transition: 'all 0.1s', opacity: 0.2 + radius / maxRadius }, style) });
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
var Visualizer = function Visualizer(_ref2) {
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
var _ref2$width = _ref2.width,
|
|
24
|
+
width = _ref2$width === undefined ? 100 : _ref2$width,
|
|
25
|
+
volume = _ref2.volume,
|
|
26
|
+
_ref2$maxRadius = _ref2.maxRadius,
|
|
27
|
+
maxRadius = _ref2$maxRadius === undefined ? 100 : _ref2$maxRadius,
|
|
28
|
+
_ref2$minRadius = _ref2.minRadius,
|
|
29
|
+
minRadius = _ref2$minRadius === undefined ? 50 : _ref2$minRadius,
|
|
30
|
+
_ref2$style = _ref2.style,
|
|
31
|
+
style = _ref2$style === undefined ? { fill: 'red' } : _ref2$style;
|
|
32
|
+
|
|
33
|
+
var radius = minRadius + (maxRadius - minRadius) * volume / 100;
|
|
26
34
|
return _react2.default.createElement(
|
|
27
|
-
'
|
|
28
|
-
|
|
29
|
-
_react2.default.createElement(
|
|
35
|
+
'div',
|
|
36
|
+
{ style: { width: width } },
|
|
37
|
+
_react2.default.createElement(
|
|
38
|
+
'svg',
|
|
39
|
+
{ viewBox: '-1 -1 2 2' },
|
|
40
|
+
_react2.default.createElement(Circle, { radius: radius, maxRadius: maxRadius, style: style })
|
|
41
|
+
)
|
|
30
42
|
);
|
|
31
43
|
};
|
|
32
44
|
|
package/recorder/index.js
CHANGED
|
@@ -40,10 +40,13 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
|
|
|
40
40
|
|
|
41
41
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
42
42
|
|
|
43
|
-
var INTERVAL = 100;
|
|
44
|
-
|
|
45
43
|
var audioContext = new _audioContext2.default();
|
|
46
44
|
|
|
45
|
+
// make the volume a value between 0 and 100
|
|
46
|
+
var formatVolume = function formatVolume(volume) {
|
|
47
|
+
return Math.max(0, Math.min(100, volume + 100));
|
|
48
|
+
};
|
|
49
|
+
|
|
47
50
|
var initRecorder = function initRecorder(_ref) {
|
|
48
51
|
var stream = _ref.stream,
|
|
49
52
|
audioContext = _ref.audioContext,
|
|
@@ -83,11 +86,12 @@ var initSpeechEvents = function initSpeechEvents(_ref3) {
|
|
|
83
86
|
_ref3$onStoppedSpeaki = _ref3.onStoppedSpeaking,
|
|
84
87
|
onStoppedSpeaking = _ref3$onStoppedSpeaki === undefined ? function () {} : _ref3$onStoppedSpeaki,
|
|
85
88
|
_ref3$onVolumeChange = _ref3.onVolumeChange,
|
|
86
|
-
onVolumeChange = _ref3$onVolumeChange === undefined ? function () {} : _ref3$onVolumeChange
|
|
89
|
+
onVolumeChange = _ref3$onVolumeChange === undefined ? function () {} : _ref3$onVolumeChange,
|
|
90
|
+
debounce = _ref3.debounce;
|
|
87
91
|
|
|
88
92
|
// Try hark
|
|
89
93
|
var options = {
|
|
90
|
-
interval:
|
|
94
|
+
interval: debounce
|
|
91
95
|
//play: true // true: allow to hear the result for debug
|
|
92
96
|
};
|
|
93
97
|
var speechEvents = (0, _hark2.default)(stream, options);
|
|
@@ -114,7 +118,6 @@ var Recorder = function (_Component) {
|
|
|
114
118
|
|
|
115
119
|
// Data
|
|
116
120
|
_this.recordStart = null;
|
|
117
|
-
_this.audioBuffer = [];
|
|
118
121
|
_this.audioStream = null;
|
|
119
122
|
|
|
120
123
|
// Methods
|
|
@@ -147,7 +150,9 @@ var Recorder = function (_Component) {
|
|
|
147
150
|
value: function init(props) {
|
|
148
151
|
var _this2 = this;
|
|
149
152
|
|
|
150
|
-
var _props$
|
|
153
|
+
var _props$debounce = props.debounce,
|
|
154
|
+
debounce = _props$debounce === undefined ? 200 : _props$debounce,
|
|
155
|
+
_props$onNotAvailable = props.onNotAvailable,
|
|
151
156
|
onNotAvailable = _props$onNotAvailable === undefined ? function () {} : _props$onNotAvailable,
|
|
152
157
|
_props$onError = props.onError,
|
|
153
158
|
onError = _props$onError === undefined ? function () {} : _props$onError,
|
|
@@ -164,7 +169,8 @@ var Recorder = function (_Component) {
|
|
|
164
169
|
stream: stream,
|
|
165
170
|
onError: onError,
|
|
166
171
|
onVolumeChange: onVolumeChange,
|
|
167
|
-
onRecordComplete: onRecordComplete
|
|
172
|
+
onRecordComplete: onRecordComplete,
|
|
173
|
+
debounce: debounce
|
|
168
174
|
});
|
|
169
175
|
}).catch(function (err) {
|
|
170
176
|
onNotAvailable(err);
|
|
@@ -178,17 +184,14 @@ var Recorder = function (_Component) {
|
|
|
178
184
|
var stream = _ref4.stream,
|
|
179
185
|
onError = _ref4.onError,
|
|
180
186
|
_onVolumeChange = _ref4.onVolumeChange,
|
|
181
|
-
onRecordComplete = _ref4.onRecordComplete
|
|
187
|
+
onRecordComplete = _ref4.onRecordComplete,
|
|
188
|
+
debounce = _ref4.debounce;
|
|
182
189
|
|
|
183
190
|
// Init worker that will do heavy calculation
|
|
184
191
|
this.audioStream = stream;
|
|
185
192
|
this.worker = initWorker({ onMessage: function onMessage(e) {
|
|
186
193
|
switch (e.data.command) {
|
|
187
|
-
case 'send_buffers':
|
|
188
|
-
_this3.audioBuffer = e.data.buffers;
|
|
189
|
-
break;
|
|
190
194
|
case 'send_WAV':
|
|
191
|
-
//const url = (window.URL || window.webkitURL).createObjectURL(e.data.audioBlob)
|
|
192
195
|
onRecordComplete(e.data.audioBlob);
|
|
193
196
|
break;
|
|
194
197
|
}
|
|
@@ -204,7 +207,8 @@ var Recorder = function (_Component) {
|
|
|
204
207
|
inputBuffer.push(e.inputBuffer.getChannelData(channel));
|
|
205
208
|
}
|
|
206
209
|
_this3.worker.postMessage({ command: 'append', timestamp: Date.now(), inputBuffer: inputBuffer });
|
|
207
|
-
}
|
|
210
|
+
},
|
|
211
|
+
debounce: debounce
|
|
208
212
|
});
|
|
209
213
|
|
|
210
214
|
// Initialize hark for silence recognition
|
|
@@ -212,19 +216,19 @@ var Recorder = function (_Component) {
|
|
|
212
216
|
stream: stream,
|
|
213
217
|
onStoppedSpeaking: function onStoppedSpeaking() {
|
|
214
218
|
try {
|
|
215
|
-
|
|
216
|
-
_this3.worker.postMessage({ command: '
|
|
217
|
-
_this3.audioBuffer = [];
|
|
219
|
+
console.log("exportWAV");
|
|
220
|
+
_this3.worker.postMessage({ command: 'exportWAV', beginning: _this3.recordStart, end: Date.now() });
|
|
218
221
|
} catch (e) {
|
|
219
222
|
onError(e);
|
|
220
223
|
}
|
|
221
224
|
},
|
|
222
225
|
onSpeaking: function onSpeaking() {
|
|
223
|
-
_this3.recordStart = Date.now() -
|
|
226
|
+
_this3.recordStart = Date.now() - debounce * 3; // give it a bit of extra time
|
|
224
227
|
},
|
|
225
228
|
onVolumeChange: function onVolumeChange(volume) {
|
|
226
|
-
_onVolumeChange(volume);
|
|
227
|
-
}
|
|
229
|
+
_onVolumeChange(formatVolume(volume));
|
|
230
|
+
},
|
|
231
|
+
debounce: debounce
|
|
228
232
|
});
|
|
229
233
|
}
|
|
230
234
|
}, {
|
package/stories/visualizer.js
CHANGED
|
@@ -61,9 +61,16 @@ var VisualizerExample = function (_Component) {
|
|
|
61
61
|
'div',
|
|
62
62
|
null,
|
|
63
63
|
_react2.default.createElement(_recorder2.default, {
|
|
64
|
+
debounce: 100,
|
|
64
65
|
onVolumeChange: this.setVolume,
|
|
65
66
|
onError: function onError(err) {
|
|
66
67
|
return console.log('error', err);
|
|
68
|
+
},
|
|
69
|
+
onRecordComplete: function onRecordComplete() {
|
|
70
|
+
return console.log('onRecordComplete');
|
|
71
|
+
},
|
|
72
|
+
onNotAvailable: function onNotAvailable() {
|
|
73
|
+
return console.log('not available');
|
|
67
74
|
}
|
|
68
75
|
}),
|
|
69
76
|
_react2.default.createElement(_Visualizer2.default, { volume: volume })
|
package/stories/wordDetector.js
CHANGED
|
@@ -37,15 +37,15 @@ var onNotAvailable = function onNotAvailable() {
|
|
|
37
37
|
var onError = function onError(e) {
|
|
38
38
|
return console.log("onError", e);
|
|
39
39
|
};
|
|
40
|
-
var onSuccess = function onSuccess(res
|
|
41
|
-
return console.log(
|
|
40
|
+
var onSuccess = function onSuccess(res) {
|
|
41
|
+
return console.log("onSucces", res);
|
|
42
42
|
};
|
|
43
|
-
var onFailure = function onFailure(res
|
|
44
|
-
return console.log(
|
|
43
|
+
var onFailure = function onFailure(res) {
|
|
44
|
+
return console.log("onFailure", res);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
var CONFIG = {
|
|
48
|
-
API_URL: '
|
|
48
|
+
API_URL: 'https://api-dev.lelivrescolaire.fr/speechtotext'
|
|
49
49
|
|
|
50
50
|
// Instanciate component with config
|
|
51
51
|
};var WordDetectorComponent = (0, _wordDetector.createWordDetector)(CONFIG);
|
|
@@ -84,7 +84,6 @@ var WordDetectorExample = function (_Component) {
|
|
|
84
84
|
onError: onError,
|
|
85
85
|
onSuccess: onSuccess,
|
|
86
86
|
onFailure: onFailure,
|
|
87
|
-
record: true,
|
|
88
87
|
onRecordComplete: onRecordComplete
|
|
89
88
|
})
|
|
90
89
|
);
|
package/wordDetector/index.js
CHANGED
|
@@ -36,9 +36,10 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
|
|
|
36
36
|
var SIMILARITY_THRESHOLD = 0.8;
|
|
37
37
|
var isSpeechRecognitionAvailable = (0, _reactSpeechRecognizer.speechRecognitionAvailable)();
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
/*
|
|
40
|
+
const debug = (wav) => {
|
|
41
|
+
FileSaver.saveAs(wav, 'test.wav')
|
|
42
|
+
}*/
|
|
42
43
|
|
|
43
44
|
var sendFileToSpeechToTextApi = function sendFileToSpeechToTextApi(API_URL, wav) {
|
|
44
45
|
return new Promise(function (resolve, reject) {
|
|
@@ -73,8 +74,7 @@ var WordDetector = function (_Component) {
|
|
|
73
74
|
var _this = _possibleConstructorReturn(this, (WordDetector.__proto__ || Object.getPrototypeOf(WordDetector)).call(this, props));
|
|
74
75
|
|
|
75
76
|
_this.state = {
|
|
76
|
-
attempts: 0
|
|
77
|
-
browserApiAvailable: true
|
|
77
|
+
attempts: 0
|
|
78
78
|
};
|
|
79
79
|
_this.onError = _this.onError.bind(_this);
|
|
80
80
|
_this.onSuccess = _this.onSuccess.bind(_this);
|
|
@@ -86,23 +86,27 @@ var WordDetector = function (_Component) {
|
|
|
86
86
|
|
|
87
87
|
_createClass(WordDetector, [{
|
|
88
88
|
key: 'onSuccess',
|
|
89
|
-
value: function onSuccess(res, attempts) {
|
|
89
|
+
value: function onSuccess(res, attempts, url) {
|
|
90
90
|
var onSuccess = this.props.onSuccess;
|
|
91
91
|
|
|
92
92
|
this.setState({
|
|
93
|
-
attempts:
|
|
93
|
+
attempts: 0
|
|
94
|
+
});
|
|
95
|
+
onSuccess({
|
|
96
|
+
res: res, attempts: attempts, url: url
|
|
94
97
|
});
|
|
95
|
-
onSuccess(res, attempts);
|
|
96
98
|
}
|
|
97
99
|
}, {
|
|
98
100
|
key: 'onFailure',
|
|
99
|
-
value: function onFailure(res, attempts) {
|
|
101
|
+
value: function onFailure(res, attempts, url) {
|
|
100
102
|
var onFailure = this.props.onFailure;
|
|
101
103
|
|
|
102
104
|
this.setState({
|
|
103
105
|
attempts: attempts
|
|
104
106
|
});
|
|
105
|
-
onFailure(
|
|
107
|
+
onFailure({
|
|
108
|
+
res: res, attempts: attempts, url: url
|
|
109
|
+
});
|
|
106
110
|
}
|
|
107
111
|
}, {
|
|
108
112
|
key: 'onError',
|
|
@@ -114,8 +118,10 @@ var WordDetector = function (_Component) {
|
|
|
114
118
|
}, {
|
|
115
119
|
key: 'onApiResult',
|
|
116
120
|
value: function onApiResult(_ref) {
|
|
117
|
-
var
|
|
118
|
-
|
|
121
|
+
var speechToText = _ref.speechToText,
|
|
122
|
+
url = _ref.url;
|
|
123
|
+
|
|
124
|
+
var transcript = speechToText && speechToText[0];
|
|
119
125
|
var attempts = this.state.attempts;
|
|
120
126
|
var _props = this.props,
|
|
121
127
|
word = _props.word,
|
|
@@ -124,7 +130,7 @@ var WordDetector = function (_Component) {
|
|
|
124
130
|
var incrementedAttempts = attempts + 1;
|
|
125
131
|
var success = compare(word, transcript);
|
|
126
132
|
var cb = success ? this.onSuccess : this.onFailure;
|
|
127
|
-
cb(transcript, incrementedAttempts);
|
|
133
|
+
cb(transcript, incrementedAttempts, url);
|
|
128
134
|
}
|
|
129
135
|
}, {
|
|
130
136
|
key: 'onRecordComplete',
|
|
@@ -133,46 +139,27 @@ var WordDetector = function (_Component) {
|
|
|
133
139
|
|
|
134
140
|
//debug(wav)
|
|
135
141
|
var _props2 = this.props,
|
|
136
|
-
alwaysUseApi = _props2.alwaysUseApi,
|
|
137
142
|
config = _props2.config,
|
|
138
143
|
onRecordComplete = _props2.onRecordComplete;
|
|
139
144
|
var API_URL = config.API_URL;
|
|
140
|
-
var browserApiAvailable = this.state.browserApiAvailable;
|
|
141
145
|
|
|
142
146
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// Upload to Speech to text Api
|
|
146
|
-
if (!useHtmlDetector) {
|
|
147
|
-
if (!API_URL) {
|
|
148
|
-
return this.onError(new Error('Missing API_URL in CONF'));
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
sendFileToSpeechToTextApi(API_URL, wav).then(function (res) {
|
|
152
|
-
_this2.onApiResult(res);
|
|
153
|
-
}).catch(function (e) {
|
|
154
|
-
_this2.onError(e);
|
|
155
|
-
});
|
|
147
|
+
if (!API_URL) {
|
|
148
|
+
return this.onError(new Error('Missing API_URL in CONF'));
|
|
156
149
|
}
|
|
157
150
|
|
|
151
|
+
sendFileToSpeechToTextApi(API_URL, wav).then(function (res) {
|
|
152
|
+
_this2.onApiResult(JSON.parse(res));
|
|
153
|
+
}).catch(function (e) {
|
|
154
|
+
_this2.onError(e);
|
|
155
|
+
});
|
|
156
|
+
|
|
158
157
|
onRecordComplete(wav);
|
|
159
158
|
}
|
|
160
159
|
}, {
|
|
161
160
|
key: 'render',
|
|
162
161
|
value: function render() {
|
|
163
|
-
|
|
164
|
-
record = _props3.record,
|
|
165
|
-
word = _props3.word,
|
|
166
|
-
compare = _props3.compare,
|
|
167
|
-
alwaysUseApi = _props3.alwaysUseApi;
|
|
168
|
-
|
|
169
|
-
var useHtmlDetector = isSpeechRecognitionAvailable && !alwaysUseApi;
|
|
170
|
-
return _react2.default.createElement(
|
|
171
|
-
'div',
|
|
172
|
-
null,
|
|
173
|
-
useHtmlDetector ? _react2.default.createElement(_reactSpeechRecognizer.WordDetector, { word: word, compare: compare, onFailure: this.onFailure, onSuccess: this.onSuccess }) : _react2.default.createElement(_recorder2.default, { onError: this.onError, onRecordComplete: this.onRecordComplete }),
|
|
174
|
-
useHtmlDetector && record && _react2.default.createElement(_recorder2.default, { onError: this.onError, onRecordComplete: this.onRecordComplete })
|
|
175
|
-
);
|
|
162
|
+
return _react2.default.createElement(_recorder2.default, { onError: this.onError, onRecordComplete: this.onRecordComplete });
|
|
176
163
|
}
|
|
177
164
|
}]);
|
|
178
165
|
|
|
@@ -180,9 +167,7 @@ var WordDetector = function (_Component) {
|
|
|
180
167
|
}(_react.Component);
|
|
181
168
|
|
|
182
169
|
WordDetector.defaultProps = {
|
|
183
|
-
alwaysUseApi: true,
|
|
184
170
|
config: {},
|
|
185
|
-
record: false,
|
|
186
171
|
word: '',
|
|
187
172
|
compare: defaultCompare,
|
|
188
173
|
onRecordComplete: function onRecordComplete() {},
|