@lls/lls-audio 0.0.60 → 0.0.62

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lls/lls-audio",
3
- "version": "0.0.60",
3
+ "version": "0.0.62",
4
4
  "main": "index.js",
5
5
  "devDependencies": {
6
6
  "@kadira/storybook": "2.21.0",
@@ -15,9 +15,11 @@
15
15
  "conventional-changelog": "1.1.0",
16
16
  "conventional-changelog-cli": "1.2.0",
17
17
  "css-loader": "0.26.1",
18
+ "file-saver": "^1.3.3",
18
19
  "react": "15.3.1",
19
20
  "react-dom": "15.3.1",
20
21
  "release-it": "2.4.0",
22
+ "similarity": "1.1.1",
21
23
  "style-loader": "0.13.1",
22
24
  "superheroes": "1.0.0"
23
25
  },
@@ -29,10 +29,12 @@ exports.default = {
29
29
  inline: {
30
30
  width: '100%'
31
31
  },
32
- volume: {
32
+ volume: _defineProperty({
33
33
  width: 100,
34
34
  cursor: 'pointer'
35
- },
35
+ }, _mediaQueries.MOBILE, {
36
+ width: 55
37
+ }),
36
38
  iconAudio: {
37
39
  color: _colors.BLUE,
38
40
  marginRight: 20,
@@ -58,8 +60,7 @@ exports.default = {
58
60
  width: 'calc(100% - 430px)',
59
61
  display: 'flex'
60
62
  }, _mediaQueries.MOBILE, {
61
- flex: '1 100%',
62
- order: 2,
63
+ width: 'calc(100% - 225px)',
63
64
  margin: '0px 28px'
64
65
  }),
65
66
  content: {
@@ -88,22 +89,36 @@ exports.default = {
88
89
  wavetimeline: _defineProperty({}, _mediaQueries.MOBILE, {
89
90
  display: 'none'
90
91
  }),
91
- loader: {
92
+ loader: _defineProperty({
92
93
  height: 60,
93
94
  color: '#00b3df',
94
95
  fontSize: 10,
95
96
  fontWeight: 'bold',
96
97
  lineHeight: '60px',
97
98
  textAlign: 'center'
98
- },
99
- loaderText: {
99
+ }, _mediaQueries.MOBILE, {
100
+ lineHeight: 1.5
101
+ }),
102
+ loaderText: _defineProperty({
100
103
  textTransform: 'uppercase'
101
- },
102
- loaderOne: {},
103
- loaderTwo: {},
104
- loaderThree: {},
104
+ }, _mediaQueries.MOBILE, {
105
+ position: 'relative',
106
+ top: 30
107
+ }),
108
+ loaderOne: _defineProperty({}, _mediaQueries.MOBILE, {
109
+ position: 'relative',
110
+ top: 30
111
+ }),
112
+ loaderTwo: _defineProperty({}, _mediaQueries.MOBILE, {
113
+ position: 'relative',
114
+ top: 30
115
+ }),
116
+ loaderThree: _defineProperty({}, _mediaQueries.MOBILE, {
117
+ position: 'relative',
118
+ top: 30
119
+ }),
105
120
  timeline: _defineProperty({
106
- width: '100%',
121
+ width: 'calc(100% - 90px)',
107
122
  margin: '0px 20px',
108
123
  position: 'relative',
109
124
  display: 'flex',
@@ -117,11 +132,13 @@ exports.default = {
117
132
  fontSize: 23,
118
133
  cursor: 'pointer'
119
134
  }, _mediaQueries.MOBILE, {
120
- marginRight: 37
135
+ display: 'none'
121
136
  }),
122
- speed_menu: {
137
+ speed_menu: _defineProperty({
123
138
  marginLeft: 10
124
- },
139
+ }, _mediaQueries.MOBILE, {
140
+ display: 'none'
141
+ }),
125
142
  close: {
126
143
  cursor: 'pointer',
127
144
  position: 'absolute',
@@ -56,6 +56,7 @@ var AudioWorker = function AudioWorker(self) {
56
56
  };
57
57
 
58
58
  var encodeWAV = function encodeWAV(samples) {
59
+ console.log("samples", samples.length);
59
60
  var buffer = new ArrayBuffer(44 + samples.length * 2);
60
61
  var view = new DataView(buffer);
61
62
 
@@ -76,7 +77,7 @@ var AudioWorker = function AudioWorker(self) {
76
77
  /* sample rate */
77
78
  view.setUint32(24, 44100, true);
78
79
  /* byte rate (sample rate * block align) */
79
- view.setUint32(28, 44100 * 4, true);
80
+ view.setUint32(28, 44100 * recBuffers.length * 2, true);
80
81
  /* block align (channel count * bytes per sample) */
81
82
  view.setUint16(32, recBuffers.length * 2, true);
82
83
  /* bits per sample */
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _react = require('react');
8
+
9
+ var _react2 = _interopRequireDefault(_react);
10
+
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+
13
+ var Circle = function Circle(_ref) {
14
+ var radius = _ref.radius,
15
+ maxRadius = _ref.maxRadius,
16
+ color = _ref.color;
17
+ return _react2.default.createElement('circle', { r: radius, cx: 100, cy: 100, style: { 'transition': 'all 0.1s', 'fill': 'red', opacity: 0.2 + radius / maxRadius } });
18
+ };
19
+
20
+ var Visualizer = function Visualizer(_ref2) {
21
+ var volume = _ref2.volume;
22
+
23
+ var radius = (100 + volume) / 2;
24
+ radius = radius < 0 ? 0 : radius;
25
+
26
+ return _react2.default.createElement(
27
+ 'svg',
28
+ null,
29
+ _react2.default.createElement(Circle, { radius: radius, maxRadius: 100 })
30
+ );
31
+ };
32
+
33
+ exports.default = Visualizer;
package/recorder/index.js CHANGED
@@ -4,32 +4,219 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
 
7
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
+
7
9
  var _react = require('react');
8
10
 
9
11
  var _react2 = _interopRequireDefault(_react);
10
12
 
11
- var _is_js = require('is_js');
13
+ var _CustomWave = require('../player/CustomWave');
14
+
15
+ var _CustomWave2 = _interopRequireDefault(_CustomWave);
16
+
17
+ var _audioContext = require('../utils/audioContext');
18
+
19
+ var _audioContext2 = _interopRequireDefault(_audioContext);
20
+
21
+ var _mediaDevices = require('../utils/mediaDevices');
12
22
 
13
- var _DesktopRecorder = require('./DesktopRecorder');
23
+ var _hark = require('hark');
14
24
 
15
- var _DesktopRecorder2 = _interopRequireDefault(_DesktopRecorder);
25
+ var _hark2 = _interopRequireDefault(_hark);
16
26
 
17
- var _MobileRecorder = require('./MobileRecorder');
27
+ var _inlineWorker = require('inline-worker');
18
28
 
19
- var _MobileRecorder2 = _interopRequireDefault(_MobileRecorder);
29
+ var _inlineWorker2 = _interopRequireDefault(_inlineWorker);
30
+
31
+ var _AudioWorker = require('./AudioWorker');
32
+
33
+ var _AudioWorker2 = _interopRequireDefault(_AudioWorker);
20
34
 
21
35
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
36
 
23
- // Check browser support
24
- var isUserMediaSupported = !!(window.navigator.getUserMedia || window.navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia || window.navigator.msGetUserMedia);
25
- var desktop = !((0, _is_js.tablet)() && (0, _is_js.mobile)());
37
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
38
+
39
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
40
+
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
+
43
+ var INTERVAL = 100;
44
+
45
+ var audioContext = new _audioContext2.default();
46
+
47
+ var initRecorder = function initRecorder(_ref) {
48
+ var stream = _ref.stream,
49
+ audioContext = _ref.audioContext,
50
+ _ref$onAudioProcess = _ref.onAudioProcess,
51
+ onAudioProcess = _ref$onAudioProcess === undefined ? function () {} : _ref$onAudioProcess;
52
+
53
+ var bufferSize = 4096;
54
+ var numberOfInputChannels = 1; // for google cloud Speech to text, we must have one (and only one) channel
55
+ var numberOfOutputChannels = 1;
56
+
57
+ // creates an audio node from the microphone incoming stream
58
+ var mediaStream = audioContext.createMediaStreamSource(stream);
59
+ var recorder = audioContext.createScriptProcessor ? audioContext.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels) : audioContext.createJavaScriptNode(bufferSize, numberOfInputChannels, numberOfOutputChannels);
60
+
61
+ recorder.onaudioprocess = onAudioProcess;
62
+
63
+ // we connect the recorder with the input stream
64
+ mediaStream.connect(recorder);
65
+ recorder.connect(audioContext.destination);
66
+
67
+ return recorder;
68
+ };
69
+
70
+ var initWorker = function initWorker(_ref2) {
71
+ var _ref2$onMessage = _ref2.onMessage,
72
+ onMessage = _ref2$onMessage === undefined ? function () {} : _ref2$onMessage;
73
+
74
+ var worker = new _inlineWorker2.default(_AudioWorker2.default, {});
75
+ worker.onmessage = onMessage;
76
+ return worker;
77
+ };
78
+
79
+ var initSpeechEvents = function initSpeechEvents(_ref3) {
80
+ var stream = _ref3.stream,
81
+ _ref3$onSpeaking = _ref3.onSpeaking,
82
+ onSpeaking = _ref3$onSpeaking === undefined ? function () {} : _ref3$onSpeaking,
83
+ _ref3$onStoppedSpeaki = _ref3.onStoppedSpeaking,
84
+ onStoppedSpeaking = _ref3$onStoppedSpeaki === undefined ? function () {} : _ref3$onStoppedSpeaki,
85
+ _ref3$onVolumeChange = _ref3.onVolumeChange,
86
+ onVolumeChange = _ref3$onVolumeChange === undefined ? function () {} : _ref3$onVolumeChange;
87
+
88
+ // Try hark
89
+ var options = {
90
+ interval: INTERVAL
91
+ //play: true // true: allow to hear the result for debug
92
+ };
93
+ var speechEvents = (0, _hark2.default)(stream, options);
26
94
 
27
- var Recorder = function Recorder(props) {
28
- return desktop ? isUserMediaSupported ? _react2.default.createElement(_DesktopRecorder2.default, props) : _react2.default.createElement(
29
- 'div',
30
- null,
31
- ' not supported '
32
- ) : _react2.default.createElement(_MobileRecorder2.default, props);
95
+ speechEvents.on('speaking', onSpeaking);
96
+ speechEvents.on('stopped_speaking', onStoppedSpeaking);
97
+ speechEvents.on('volume_change', onVolumeChange);
98
+
99
+ return speechEvents;
33
100
  };
34
101
 
35
- exports.default = Recorder;
102
+ var DesktopAudioRecorder = function (_Component) {
103
+ _inherits(DesktopAudioRecorder, _Component);
104
+
105
+ function DesktopAudioRecorder(props) {
106
+ _classCallCheck(this, DesktopAudioRecorder);
107
+
108
+ // Instances
109
+ var _this = _possibleConstructorReturn(this, (DesktopAudioRecorder.__proto__ || Object.getPrototypeOf(DesktopAudioRecorder)).call(this, props));
110
+
111
+ _this.worker = null;
112
+ _this.recorder = null;
113
+ _this.speechEvents = null;
114
+
115
+ // Data
116
+ _this.recordStart = null;
117
+ _this.audioBuffer = [];
118
+
119
+ // Methods
120
+ _this.init = _this.init.bind(_this);
121
+ _this.initStream = _this.initStream.bind(_this);
122
+ return _this;
123
+ }
124
+
125
+ _createClass(DesktopAudioRecorder, [{
126
+ key: 'componentDidMount',
127
+ value: function componentDidMount() {
128
+ this.init(this.props);
129
+ }
130
+ }, {
131
+ key: 'init',
132
+ value: function init(props) {
133
+ var _this2 = this;
134
+
135
+ var _props$onError = props.onError,
136
+ onError = _props$onError === undefined ? function () {} : _props$onError,
137
+ _props$onVolumeChange = props.onVolumeChange,
138
+ onVolumeChange = _props$onVolumeChange === undefined ? function () {} : _props$onVolumeChange,
139
+ _props$onRecordComple = props.onRecordComplete,
140
+ onRecordComplete = _props$onRecordComple === undefined ? function () {} : _props$onRecordComple;
141
+
142
+
143
+ (0, _mediaDevices.shimMediaDevices)();
144
+
145
+ window.navigator.mediaDevices.getUserMedia({ audio: true }).then(function (stream) {
146
+ _this2.initStream({
147
+ stream: stream,
148
+ onError: onError,
149
+ onVolumeChange: onVolumeChange,
150
+ onRecordComplete: onRecordComplete
151
+ });
152
+ }).catch(function (err) {
153
+ onError(err);
154
+ });
155
+ }
156
+ }, {
157
+ key: 'initStream',
158
+ value: function initStream(_ref4) {
159
+ var _this3 = this;
160
+
161
+ var stream = _ref4.stream,
162
+ onError = _ref4.onError,
163
+ _onVolumeChange = _ref4.onVolumeChange,
164
+ onRecordComplete = _ref4.onRecordComplete;
165
+
166
+ // Init worker that will do heavy calculation
167
+ this.worker = initWorker({ onMessage: function onMessage(e) {
168
+ switch (e.data.command) {
169
+ case 'send_buffers':
170
+ _this3.audioBuffer = e.data.buffers;
171
+ break;
172
+ case 'send_WAV':
173
+ //const url = (window.URL || window.webkitURL).createObjectURL(e.data.audioBlob)
174
+ onRecordComplete(e.data.audioBlob);
175
+ break;
176
+ }
177
+ } });
178
+
179
+ // Init recorder
180
+ this.recorder = initRecorder({
181
+ stream: stream,
182
+ audioContext: audioContext,
183
+ onAudioProcess: function onAudioProcess(e) {
184
+ var inputBuffer = [];
185
+ for (var channel = 0; channel < e.inputBuffer.numberOfChannels; channel++) {
186
+ inputBuffer.push(e.inputBuffer.getChannelData(channel));
187
+ }
188
+ _this3.worker.postMessage({ command: 'append', timestamp: Date.now(), inputBuffer: inputBuffer });
189
+ }
190
+ });
191
+
192
+ // Initialize hark for silence recognition
193
+ this.speechEvents = initSpeechEvents({
194
+ stream: stream,
195
+ onStoppedSpeaking: function onStoppedSpeaking() {
196
+ try {
197
+ _this3.worker.postMessage({ command: 'exportWAV', buffers: _this3.audioBuffer, beginning: _this3.recordStart, end: Date.now() });
198
+ _this3.worker.postMessage({ command: 'clean' });
199
+ _this3.audioBuffer = [];
200
+ } catch (e) {
201
+ onError(e);
202
+ }
203
+ },
204
+ onSpeaking: function onSpeaking() {
205
+ _this3.recordStart = Date.now() - INTERVAL * 3; // give it a bit of extra time
206
+ },
207
+ onVolumeChange: function onVolumeChange(volume) {
208
+ _onVolumeChange(volume);
209
+ }
210
+ });
211
+ }
212
+ }, {
213
+ key: 'render',
214
+ value: function render() {
215
+ return null;
216
+ }
217
+ }]);
218
+
219
+ return DesktopAudioRecorder;
220
+ }(_react.Component);
221
+
222
+ exports.default = DesktopAudioRecorder;
package/stories/index.js CHANGED
@@ -14,12 +14,17 @@ var _playerRange = require('./playerRange');
14
14
 
15
15
  var _playerRange2 = _interopRequireDefault(_playerRange);
16
16
 
17
- var _recorder = require('./recorder');
17
+ var _visualizer = require('./visualizer');
18
18
 
19
- var _recorder2 = _interopRequireDefault(_recorder);
19
+ var _visualizer2 = _interopRequireDefault(_visualizer);
20
+
21
+ var _wordDetector = require('./wordDetector');
22
+
23
+ var _wordDetector2 = _interopRequireDefault(_wordDetector);
20
24
 
21
25
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
26
 
27
+ //import PlayerCustom from './playerCustom'
23
28
  (0, _storybook.storiesOf)('Player', module).add('Custom waveform', function () {
24
29
  return _react2.default.createElement(_player2.default, null);
25
30
  }).add('Ranges', function () {
@@ -31,8 +36,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
31
36
  }).add('Caption', function () {
32
37
  return _react2.default.createElement(_player2.default, { caption: 'Je suis une caption :)' });
33
38
  });
34
- //import PlayerCustom from './playerCustom'
35
-
36
- (0, _storybook.storiesOf)('Recorder', module).add('Normal', function () {
37
- return _react2.default.createElement(_recorder2.default, null);
39
+ (0, _storybook.storiesOf)('Recorder', module).add('Visualizer', function () {
40
+ return _react2.default.createElement(_visualizer2.default, null);
41
+ });
42
+ (0, _storybook.storiesOf)('Word detector', module).add('Normal', function () {
43
+ return _react2.default.createElement(_wordDetector2.default, null);
38
44
  });
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
+
9
+ var _react = require('react');
10
+
11
+ var _react2 = _interopRequireDefault(_react);
12
+
13
+ var _player = require('../player');
14
+
15
+ var _player2 = _interopRequireDefault(_player);
16
+
17
+ var _recorder = require('../recorder');
18
+
19
+ var _recorder2 = _interopRequireDefault(_recorder);
20
+
21
+ var _Visualizer = require('../recorder/Visualizer');
22
+
23
+ var _Visualizer2 = _interopRequireDefault(_Visualizer);
24
+
25
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
+
27
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28
+
29
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
30
+
31
+ 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; }
32
+
33
+ var VisualizerExample = function (_Component) {
34
+ _inherits(VisualizerExample, _Component);
35
+
36
+ function VisualizerExample(props) {
37
+ _classCallCheck(this, VisualizerExample);
38
+
39
+ var _this = _possibleConstructorReturn(this, (VisualizerExample.__proto__ || Object.getPrototypeOf(VisualizerExample)).call(this, props));
40
+
41
+ _this.state = {
42
+ volume: 0
43
+ };
44
+ _this.setVolume = _this.setVolume.bind(_this);
45
+ return _this;
46
+ }
47
+
48
+ _createClass(VisualizerExample, [{
49
+ key: 'setVolume',
50
+ value: function setVolume(volume) {
51
+ this.setState({
52
+ volume: volume
53
+ });
54
+ }
55
+ }, {
56
+ key: 'render',
57
+ value: function render() {
58
+ var volume = this.state.volume;
59
+
60
+ return _react2.default.createElement(
61
+ 'div',
62
+ null,
63
+ _react2.default.createElement(_recorder2.default, {
64
+ onVolumeChange: this.setVolume,
65
+ onError: function onError(err) {
66
+ return console.log('error', err);
67
+ }
68
+ }),
69
+ _react2.default.createElement(_Visualizer2.default, { volume: volume })
70
+ );
71
+ }
72
+ }]);
73
+
74
+ return VisualizerExample;
75
+ }(_react.Component);
76
+
77
+ exports.default = VisualizerExample;
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
+
9
+ var _react = require('react');
10
+
11
+ var _react2 = _interopRequireDefault(_react);
12
+
13
+ var _player = require('../player');
14
+
15
+ var _player2 = _interopRequireDefault(_player);
16
+
17
+ var _wordDetector = require('../wordDetector');
18
+
19
+ var _wordDetector2 = _interopRequireDefault(_wordDetector);
20
+
21
+ var _Visualizer = require('../recorder/Visualizer');
22
+
23
+ var _Visualizer2 = _interopRequireDefault(_Visualizer);
24
+
25
+ var _recorder = require('../recorder');
26
+
27
+ var _recorder2 = _interopRequireDefault(_recorder);
28
+
29
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30
+
31
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
32
+
33
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
34
+
35
+ 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; }
36
+
37
+ var onError = function onError(e) {
38
+ return console.log("onError", e);
39
+ };
40
+ var onSuccess = function onSuccess(res, attempts) {
41
+ return console.log({ res: res, attempts: attempts });
42
+ };
43
+ var onFailure = function onFailure(res, attempts) {
44
+ return console.log({ res: res, attempts: attempts });
45
+ };
46
+
47
+ var WordDetectorExample = function (_Component) {
48
+ _inherits(WordDetectorExample, _Component);
49
+
50
+ function WordDetectorExample(props) {
51
+ _classCallCheck(this, WordDetectorExample);
52
+
53
+ var _this = _possibleConstructorReturn(this, (WordDetectorExample.__proto__ || Object.getPrototypeOf(WordDetectorExample)).call(this, props));
54
+
55
+ _this.state = {
56
+ volume: 0
57
+ };
58
+ _this.setVolume = _this.setVolume.bind(_this);
59
+ return _this;
60
+ }
61
+
62
+ _createClass(WordDetectorExample, [{
63
+ key: 'setVolume',
64
+ value: function setVolume(volume) {
65
+ this.setState({
66
+ volume: volume
67
+ });
68
+ }
69
+ }, {
70
+ key: 'render',
71
+ value: function render() {
72
+ var volume = this.state.volume;
73
+
74
+ return _react2.default.createElement(
75
+ 'div',
76
+ null,
77
+ _react2.default.createElement(
78
+ 'div',
79
+ null,
80
+ 'Say "Hello"'
81
+ ),
82
+ _react2.default.createElement(_wordDetector2.default, {
83
+ word: 'hello',
84
+ onVolumeChange: this.setVolume,
85
+ onError: onError,
86
+ onSuccess: onSuccess,
87
+ onFailure: onFailure
88
+ }),
89
+ _react2.default.createElement(_Visualizer2.default, { volume: volume })
90
+ );
91
+ }
92
+ }]);
93
+
94
+ return WordDetectorExample;
95
+ }(_react.Component);
96
+
97
+ exports.default = WordDetectorExample;
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
+
9
+ var _react = require('react');
10
+
11
+ var _react2 = _interopRequireDefault(_react);
12
+
13
+ var _recorder = require('../recorder');
14
+
15
+ var _recorder2 = _interopRequireDefault(_recorder);
16
+
17
+ var _similarity = require('similarity');
18
+
19
+ var _similarity2 = _interopRequireDefault(_similarity);
20
+
21
+ var _fileSaver = require('file-saver');
22
+
23
+ var _fileSaver2 = _interopRequireDefault(_fileSaver);
24
+
25
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
+
27
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28
+
29
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
30
+
31
+ 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; }
32
+
33
+ var API_URL = 'http://localhost:3004/speechtotext';
34
+ var SIMILARITY_THRESHOLD = 0.8;
35
+
36
+ var debug = function debug(wav) {
37
+ _fileSaver2.default.saveAs(wav, 'test.wav');
38
+ };
39
+
40
+ var sendFileToSpeechToTextApi = function sendFileToSpeechToTextApi(wav) {
41
+ return new Promise(function (resolve, reject) {
42
+ var xhr = new XMLHttpRequest();
43
+ xhr.open('POST', API_URL, true);
44
+
45
+ xhr.onreadystatechange = function () {
46
+ if (xhr.readyState == 4 && xhr.status == 200) {
47
+ console.log('Speech to text: ', xhr.responseText);
48
+ resolve(xhr.responseText);
49
+ }
50
+ };
51
+ xhr.onerror = function () {
52
+ reject();
53
+ };
54
+ xhr.setRequestHeader('Content-Type', 'audio/wav');
55
+ xhr.send(wav);
56
+ });
57
+ };
58
+
59
+ var defaultCompare = function defaultCompare() {
60
+ var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
61
+ var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
62
+ return (0, _similarity2.default)(a.toLowerCase().trim(), b.toLowerCase().trim()) > SIMILARITY_THRESHOLD;
63
+ };
64
+
65
+ var WordDetector = function (_Component) {
66
+ _inherits(WordDetector, _Component);
67
+
68
+ function WordDetector(props) {
69
+ _classCallCheck(this, WordDetector);
70
+
71
+ var _this = _possibleConstructorReturn(this, (WordDetector.__proto__ || Object.getPrototypeOf(WordDetector)).call(this, props));
72
+
73
+ _this.state = {
74
+ attempts: 0
75
+ };
76
+ _this.onError = _this.onError.bind(_this);
77
+ _this.onResult = _this.onResult.bind(_this);
78
+ _this.onRecordComplete = _this.onRecordComplete.bind(_this);
79
+ return _this;
80
+ }
81
+
82
+ _createClass(WordDetector, [{
83
+ key: 'onRecordComplete',
84
+ value: function onRecordComplete(wav) {
85
+ var _this2 = this;
86
+
87
+ //debug(wav)
88
+
89
+ sendFileToSpeechToTextApi(wav).then(function (res) {
90
+ _this2.onResult(res);
91
+ }).catch(function (e) {
92
+ _this2.onError(e);
93
+ });
94
+ }
95
+ }, {
96
+ key: 'onError',
97
+ value: function onError(e) {
98
+ var _props$onError = this.props.onError,
99
+ onError = _props$onError === undefined ? function () {} : _props$onError;
100
+
101
+ onError(e);
102
+ }
103
+ }, {
104
+ key: 'onResult',
105
+ value: function onResult() {
106
+ var res = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
107
+ var attempts = this.state.attempts;
108
+ var _props = this.props,
109
+ word = _props.word,
110
+ _props$onSuccess = _props.onSuccess,
111
+ onSuccess = _props$onSuccess === undefined ? function () {} : _props$onSuccess,
112
+ _props$onFailure = _props.onFailure,
113
+ onFailure = _props$onFailure === undefined ? function () {} : _props$onFailure,
114
+ _props$compare = _props.compare,
115
+ compare = _props$compare === undefined ? defaultCompare : _props$compare;
116
+
117
+ var incrementedAttempts = attempts + 1;
118
+ var success = compare(word, res);
119
+ this.setState({
120
+ attempts: success ? 0 : incrementedAttempts
121
+ }, function () {
122
+ var cb = success ? onSuccess : onFailure;
123
+ cb(res, incrementedAttempts);
124
+ });
125
+ }
126
+ }, {
127
+ key: 'render',
128
+ value: function render() {
129
+ var _props$onVolumeChange = this.props.onVolumeChange,
130
+ onVolumeChange = _props$onVolumeChange === undefined ? function () {} : _props$onVolumeChange;
131
+
132
+ return _react2.default.createElement(_recorder2.default, { onError: this.onError, onVolumeChange: onVolumeChange, onRecordComplete: this.onRecordComplete });
133
+ }
134
+ }]);
135
+
136
+ return WordDetector;
137
+ }(_react.Component);
138
+
139
+ exports.default = WordDetector;
@@ -1,214 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
-
7
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
-
9
- var _react = require('react');
10
-
11
- var _react2 = _interopRequireDefault(_react);
12
-
13
- var _CustomWave = require('../player/CustomWave');
14
-
15
- var _CustomWave2 = _interopRequireDefault(_CustomWave);
16
-
17
- var _audioContext = require('../utils/audioContext');
18
-
19
- var _audioContext2 = _interopRequireDefault(_audioContext);
20
-
21
- var _mediaDevices = require('../utils/mediaDevices');
22
-
23
- var _hark = require('hark');
24
-
25
- var _hark2 = _interopRequireDefault(_hark);
26
-
27
- var _inlineWorker = require('inline-worker');
28
-
29
- var _inlineWorker2 = _interopRequireDefault(_inlineWorker);
30
-
31
- var _AudioWorker = require('./AudioWorker');
32
-
33
- var _AudioWorker2 = _interopRequireDefault(_AudioWorker);
34
-
35
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
36
-
37
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
38
-
39
- function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
40
-
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
-
43
- var INTERVAL = 100;
44
-
45
- var audioContext = new _audioContext2.default();
46
-
47
- var initRecorder = function initRecorder(_ref) {
48
- var stream = _ref.stream,
49
- audioContext = _ref.audioContext,
50
- _ref$onAudioProcess = _ref.onAudioProcess,
51
- onAudioProcess = _ref$onAudioProcess === undefined ? function () {} : _ref$onAudioProcess;
52
-
53
- var bufferSize = 4096;
54
- var numberOfInputChannels = 1; // for google cloud Speech to text, we must have one (and only one) channel
55
- var numberOfOutputChannels = 1;
56
-
57
- // creates an audio node from the microphone incoming stream
58
- var mediaStream = audioContext.createMediaStreamSource(stream);
59
- var recorder = audioContext.createScriptProcessor ? audioContext.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels) : audioContext.createJavaScriptNode(bufferSize, numberOfInputChannels, numberOfOutputChannels);
60
-
61
- recorder.onaudioprocess = onAudioProcess;
62
-
63
- // we connect the recorder with the input stream
64
- mediaStream.connect(recorder);
65
- recorder.connect(audioContext.destination);
66
-
67
- return recorder;
68
- };
69
-
70
- var initSpeechEvents = function initSpeechEvents(_ref2) {
71
- var stream = _ref2.stream,
72
- _ref2$onSpeaking = _ref2.onSpeaking,
73
- onSpeaking = _ref2$onSpeaking === undefined ? function () {} : _ref2$onSpeaking,
74
- _ref2$onStoppedSpeaki = _ref2.onStoppedSpeaking,
75
- onStoppedSpeaking = _ref2$onStoppedSpeaki === undefined ? function () {} : _ref2$onStoppedSpeaki,
76
- _ref2$onVolumeChange = _ref2.onVolumeChange,
77
- onVolumeChange = _ref2$onVolumeChange === undefined ? function () {} : _ref2$onVolumeChange;
78
-
79
- // Try hark
80
- var options = {
81
- interval: INTERVAL
82
- };
83
- var speechEvents = (0, _hark2.default)(stream, options);
84
-
85
- speechEvents.on('speaking', onSpeaking);
86
- speechEvents.on('stopped_speaking', onStoppedSpeaking);
87
- speechEvents.on('volume_change', onVolumeChange);
88
-
89
- return speechEvents;
90
- };
91
-
92
- var DesktopAudioRecorder = function (_Component) {
93
- _inherits(DesktopAudioRecorder, _Component);
94
-
95
- function DesktopAudioRecorder(props) {
96
- _classCallCheck(this, DesktopAudioRecorder);
97
-
98
- var _this = _possibleConstructorReturn(this, (DesktopAudioRecorder.__proto__ || Object.getPrototypeOf(DesktopAudioRecorder)).call(this, props));
99
-
100
- _this.recordStart = null;
101
- _this.audioBuffer = [];
102
- _this.init = _this.init.bind(_this);
103
- _this.initStream = _this.initStream.bind(_this);
104
- return _this;
105
- }
106
-
107
- _createClass(DesktopAudioRecorder, [{
108
- key: 'componentDidMount',
109
- value: function componentDidMount() {
110
- this.init(this.props);
111
- }
112
- }, {
113
- key: 'init',
114
- value: function init(props) {
115
- var _this2 = this;
116
-
117
- var _props$onError = props.onError,
118
- onError = _props$onError === undefined ? function () {} : _props$onError,
119
- _props$onVolumeChange = props.onVolumeChange,
120
- onVolumeChange = _props$onVolumeChange === undefined ? function () {} : _props$onVolumeChange,
121
- _props$onRecordComple = props.onRecordComplete,
122
- onRecordComplete = _props$onRecordComple === undefined ? function () {} : _props$onRecordComple;
123
-
124
-
125
- (0, _mediaDevices.shimMediaDevices)();
126
- window.navigator.mediaDevices.getUserMedia({ audio: true }).then(function (stream) {
127
- _this2.initStream({
128
- stream: stream,
129
- onError: onError,
130
- onVolumeChange: onVolumeChange,
131
- onRecordComplete: onRecordComplete
132
- });
133
- }).catch(function (err) {
134
- onError(err);
135
- });
136
-
137
- this.initWorker();
138
- }
139
- }, {
140
- key: 'initStream',
141
- value: function initStream(_ref3) {
142
- var _this3 = this;
143
-
144
- var stream = _ref3.stream,
145
- onError = _ref3.onError,
146
- _onVolumeChange = _ref3.onVolumeChange,
147
- onRecordComplete = _ref3.onRecordComplete;
148
-
149
- // Init recorder
150
- var recorder = initRecorder({
151
- stream: stream,
152
- audioContext: audioContext,
153
- onAudioProcess: function onAudioProcess(e) {
154
- var inputBuffer = [];
155
- for (var channel = 0; channel < e.inputBuffer.numberOfChannels; channel++) {
156
- inputBuffer.push(e.inputBuffer.getChannelData(channel));
157
- }
158
- _this3.worker.postMessage({ command: 'append', timestamp: Date.now(), inputBuffer: inputBuffer });
159
- }
160
- });
161
-
162
- // Initialize hark for silence recognition
163
- var speechEvents = initSpeechEvents({
164
- stream: stream,
165
- onStoppedSpeaking: function onStoppedSpeaking() {
166
- console.log('stop');
167
- try {
168
- _this3.worker.postMessage({ command: 'exportWAV', buffers: _this3.audioBuffer, beginning: _this3.recordStart, end: Date.now() });
169
- _this3.worker.postMessage({ command: 'clean' });
170
- _this3.audioBuffer = [];
171
- } catch (e) {
172
- onError(e);
173
- }
174
- },
175
- onSpeaking: function onSpeaking() {
176
- console.log('start');
177
- _this3.recordStart = Date.now() - INTERVAL * 3; // give it a bit of extra time
178
- },
179
- onVolumeChange: function onVolumeChange(volume) {
180
- _onVolumeChange(volume);
181
- }
182
- });
183
- }
184
- }, {
185
- key: 'initWorker',
186
- value: function initWorker() {
187
- var _this4 = this;
188
-
189
- this.worker = new _inlineWorker2.default(_AudioWorker2.default, {});
190
-
191
- this.worker.onmessage = function (e) {
192
- switch (e.data.command) {
193
- case 'send_buffers':
194
- _this4.audioBuffer = e.data.buffers;
195
- break;
196
- case 'send_WAV':
197
- console.log('send_WAV');
198
- //const url = (window.URL || window.webkitURL).createObjectURL(e.data.audioBlob)
199
- _this4.props.onRecordComplete(e.data.audioBlob);
200
- break;
201
- }
202
- };
203
- }
204
- }, {
205
- key: 'render',
206
- value: function render() {
207
- return null;
208
- }
209
- }]);
210
-
211
- return DesktopAudioRecorder;
212
- }(_react.Component);
213
-
214
- exports.default = DesktopAudioRecorder;
@@ -1,47 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
-
7
- var _react = require('react');
8
-
9
- var _react2 = _interopRequireDefault(_react);
10
-
11
- var _player = require('../player');
12
-
13
- var _player2 = _interopRequireDefault(_player);
14
-
15
- var _recorder = require('../recorder');
16
-
17
- var _recorder2 = _interopRequireDefault(_recorder);
18
-
19
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
-
21
- var API_URL = 'http://localhost:3004/speechtotext';
22
-
23
- var sendFile = function sendFile(wav) {
24
- var xhr = new XMLHttpRequest();
25
- xhr.onreadystatechange = function () {
26
- if (xhr.readyState == 4 && xhr.status == 200) {
27
- console.log('Speech to text: ', xhr.responseText);
28
- }
29
- };
30
- xhr.open('POST', API_URL, false);
31
- xhr.setRequestHeader('Content-Type', 'audio/wav');
32
- xhr.send(wav);
33
- };
34
-
35
- var RecorderExample = function RecorderExample() {
36
- return _react2.default.createElement(_recorder2.default, {
37
- onVolumeChange: function onVolumeChange(vol) {},
38
- onError: function onError(err) {
39
- return console.log('error', err);
40
- },
41
- onRecordComplete: function onRecordComplete(wax) {
42
- return sendFile(wax);
43
- }
44
- });
45
- };
46
-
47
- exports.default = RecorderExample;