@lls/lls-audio 0.0.14 → 0.0.16
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 +2 -2
- package/player/index.js +8 -6
- package/recorder/DesktopAudioRecorder.js +26 -0
- package/recorder/DesktopRecorder.js +0 -1
- package/stories/player.js +1 -1
- package/stories/recorder.js +2 -2
- package/utils/audio.js +90 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lls/lls-audio",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@kadira/storybook": "^2.21.0",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"start": "npm run storybook",
|
|
41
|
-
"storybook": "start-storybook -p 9009 -s
|
|
41
|
+
"storybook": "start-storybook -p 9009 -s dist/stories",
|
|
42
42
|
"deploy-storybook": "storybook-to-ghpages",
|
|
43
43
|
"build": "rm -rf dist && mkdir dist && babel -d dist src",
|
|
44
44
|
"copy:package": "cp -R package.json dist/",
|
package/player/index.js
CHANGED
|
@@ -109,7 +109,7 @@ var Player = function (_Component) {
|
|
|
109
109
|
}, {
|
|
110
110
|
key: 'componentWillReceiveProps',
|
|
111
111
|
value: function componentWillReceiveProps(newProps) {
|
|
112
|
-
if (newProps.
|
|
112
|
+
if (newProps.src !== this.props.src) {
|
|
113
113
|
this.initialize(newProps);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
@@ -138,9 +138,9 @@ var Player = function (_Component) {
|
|
|
138
138
|
value: function initialize(props) {
|
|
139
139
|
var _this3 = this;
|
|
140
140
|
|
|
141
|
-
var
|
|
141
|
+
var src = props.src;
|
|
142
142
|
|
|
143
|
-
(0, _audio.getWaveform)(
|
|
143
|
+
(0, _audio.getWaveform)(src).then(function (waveform) {
|
|
144
144
|
_this3.setState({ waveform: waveform, loading: false });
|
|
145
145
|
});
|
|
146
146
|
}
|
|
@@ -149,7 +149,9 @@ var Player = function (_Component) {
|
|
|
149
149
|
value: function render() {
|
|
150
150
|
var _this4 = this;
|
|
151
151
|
|
|
152
|
-
var
|
|
152
|
+
var _props = this.props,
|
|
153
|
+
src = _props.src,
|
|
154
|
+
className = _props.className;
|
|
153
155
|
var _state = this.state,
|
|
154
156
|
loading = _state.loading,
|
|
155
157
|
duration = _state.duration,
|
|
@@ -167,7 +169,7 @@ var Player = function (_Component) {
|
|
|
167
169
|
|
|
168
170
|
return _react2.default.createElement(
|
|
169
171
|
'div',
|
|
170
|
-
{ className: 'Audio_player ' + (0, _noImportant.css)(styles.player) },
|
|
172
|
+
{ className: 'Audio_player ' + (0, _noImportant.css)(styles.player) + ' ' + className },
|
|
171
173
|
_react2.default.createElement(
|
|
172
174
|
'div',
|
|
173
175
|
{ className: (0, _noImportant.css)(styles.play_and_stop), onClick: function onClick() {
|
|
@@ -177,7 +179,7 @@ var Player = function (_Component) {
|
|
|
177
179
|
),
|
|
178
180
|
_react2.default.createElement(_Audio2.default, { onChange: function onChange(state) {
|
|
179
181
|
return _this4.setState(_extends({}, state));
|
|
180
|
-
}, ref: 'audio', src:
|
|
182
|
+
}, ref: 'audio', src: src }),
|
|
181
183
|
_react2.default.createElement(
|
|
182
184
|
'div',
|
|
183
185
|
{ className: (0, _noImportant.css)(styles.timeline), ref: 'container' },
|
|
@@ -109,6 +109,7 @@ var DesktopAudioRecorder = function (_Component) {
|
|
|
109
109
|
key: 'record',
|
|
110
110
|
value: function record() {
|
|
111
111
|
this.setState({
|
|
112
|
+
recordedData: null,
|
|
112
113
|
isRecording: true
|
|
113
114
|
});
|
|
114
115
|
}
|
|
@@ -150,12 +151,37 @@ var DesktopAudioRecorder = function (_Component) {
|
|
|
150
151
|
value: function onMediaError(e) {
|
|
151
152
|
console.error('media error', e);
|
|
152
153
|
}
|
|
154
|
+
|
|
155
|
+
// This is just for demo purposes: in real life we'll upload the file somewhere
|
|
156
|
+
|
|
157
|
+
}, {
|
|
158
|
+
key: 'updateAudioDom',
|
|
159
|
+
value: function updateAudioDom() {
|
|
160
|
+
var recordedData = this.state.recordedData;
|
|
161
|
+
|
|
162
|
+
var audioEl = document.querySelector('audio');
|
|
163
|
+
|
|
164
|
+
if (audioEl) {
|
|
165
|
+
var wav = (0, _audio.audioBufferToWav)(recordedData);
|
|
166
|
+
var audioBlob = new Blob([wav], { type: 'audio/wav' });
|
|
167
|
+
var reader = new FileReader();
|
|
168
|
+
reader.onload = function (e) {
|
|
169
|
+
// e.target.result will hold the base64 data.
|
|
170
|
+
// Note: It includes the pre-text "data:audio/<format>;base64,<base64 data>"
|
|
171
|
+
audioEl.src = e.target.result;
|
|
172
|
+
};
|
|
173
|
+
reader.readAsDataURL(audioBlob);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
153
176
|
}, {
|
|
154
177
|
key: 'stopRecording',
|
|
155
178
|
value: function stopRecording() {
|
|
156
179
|
this.setState({
|
|
157
180
|
isRecording: false
|
|
158
181
|
});
|
|
182
|
+
|
|
183
|
+
// Update audio element with new file
|
|
184
|
+
this.updateAudioDom();
|
|
159
185
|
}
|
|
160
186
|
}]);
|
|
161
187
|
|
|
@@ -118,7 +118,6 @@ var DesktopRecorder = function (_Component) {
|
|
|
118
118
|
var recordedData = this.state.recordedData;
|
|
119
119
|
|
|
120
120
|
var mergedBuffer = (0, _audio.appendBuffer)(recordedData, audioBuffer);
|
|
121
|
-
console.log("mergedBuffer", mergedBuffer);
|
|
122
121
|
this.setState({
|
|
123
122
|
recordedData: mergedBuffer
|
|
124
123
|
});
|
package/stories/player.js
CHANGED
|
@@ -62,7 +62,7 @@ var PlayerExample = function (_Component) {
|
|
|
62
62
|
'http://lls-media-public.s3.amazonaws.com/upload/LeLivreScolaire/p15vcjbl4lvpl9l7g8ov8ammh1.mp3'
|
|
63
63
|
)
|
|
64
64
|
),
|
|
65
|
-
_react2.default.createElement(_player2.default, {
|
|
65
|
+
_react2.default.createElement(_player2.default, { src: this.state.url })
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
}]);
|
package/stories/recorder.js
CHANGED
|
@@ -22,8 +22,8 @@ var RecorderExample = function RecorderExample() {
|
|
|
22
22
|
return _react2.default.createElement(
|
|
23
23
|
'div',
|
|
24
24
|
null,
|
|
25
|
-
_react2.default.createElement(
|
|
26
|
-
_react2.default.createElement(
|
|
25
|
+
_react2.default.createElement(_recorder2.default, null),
|
|
26
|
+
_react2.default.createElement('audio', { controls: true })
|
|
27
27
|
);
|
|
28
28
|
};
|
|
29
29
|
|
package/utils/audio.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.convertBlobToaudioBuffer = exports.appendBuffer = exports.convertAudioBufferToWaveform = exports.getWaveform = undefined;
|
|
6
|
+
exports.audioBufferToWav = exports.convertBlobToaudioBuffer = exports.appendBuffer = exports.convertAudioBufferToWaveform = exports.getWaveform = undefined;
|
|
7
7
|
|
|
8
8
|
var _audioContext = require('./audioContext');
|
|
9
9
|
|
|
@@ -120,4 +120,93 @@ var convertBlobToaudioBuffer = exports.convertBlobToaudioBuffer = function conve
|
|
|
120
120
|
});
|
|
121
121
|
};
|
|
122
122
|
fileReader.readAsArrayBuffer(blob);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
var audioBufferToWav = exports.audioBufferToWav = function audioBufferToWav(buffer, opt) {
|
|
126
|
+
opt = opt || {};
|
|
127
|
+
|
|
128
|
+
var numChannels = buffer.numberOfChannels;
|
|
129
|
+
var sampleRate = buffer.sampleRate;
|
|
130
|
+
var format = opt.float32 ? 3 : 1;
|
|
131
|
+
var bitDepth = format === 3 ? 32 : 16;
|
|
132
|
+
|
|
133
|
+
var result = numChannels === 2 ? interleave(buffer.getChannelData(0), buffer.getChannelData(1)) : buffer.getChannelData(0);
|
|
134
|
+
|
|
135
|
+
return encodeWAV(result, format, sampleRate, numChannels, bitDepth);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
var encodeWAV = function encodeWAV(samples, format, sampleRate, numChannels, bitDepth) {
|
|
139
|
+
var bytesPerSample = bitDepth / 8;
|
|
140
|
+
var blockAlign = numChannels * bytesPerSample;
|
|
141
|
+
|
|
142
|
+
var buffer = new ArrayBuffer(44 + samples.length * bytesPerSample);
|
|
143
|
+
var view = new DataView(buffer);
|
|
144
|
+
|
|
145
|
+
/* RIFF identifier */
|
|
146
|
+
writeString(view, 0, 'RIFF');
|
|
147
|
+
/* RIFF chunk length */
|
|
148
|
+
view.setUint32(4, 36 + samples.length * bytesPerSample, true);
|
|
149
|
+
/* RIFF type */
|
|
150
|
+
writeString(view, 8, 'WAVE');
|
|
151
|
+
/* format chunk identifier */
|
|
152
|
+
writeString(view, 12, 'fmt ');
|
|
153
|
+
/* format chunk length */
|
|
154
|
+
view.setUint32(16, 16, true);
|
|
155
|
+
/* sample format (raw) */
|
|
156
|
+
view.setUint16(20, format, true);
|
|
157
|
+
/* channel count */
|
|
158
|
+
view.setUint16(22, numChannels, true);
|
|
159
|
+
/* sample rate */
|
|
160
|
+
view.setUint32(24, sampleRate, true);
|
|
161
|
+
/* byte rate (sample rate * block align) */
|
|
162
|
+
view.setUint32(28, sampleRate * blockAlign, true);
|
|
163
|
+
/* block align (channel count * bytes per sample) */
|
|
164
|
+
view.setUint16(32, blockAlign, true);
|
|
165
|
+
/* bits per sample */
|
|
166
|
+
view.setUint16(34, bitDepth, true);
|
|
167
|
+
/* data chunk identifier */
|
|
168
|
+
writeString(view, 36, 'data');
|
|
169
|
+
/* data chunk length */
|
|
170
|
+
view.setUint32(40, samples.length * bytesPerSample, true);
|
|
171
|
+
if (format === 1) {
|
|
172
|
+
// Raw PCM
|
|
173
|
+
floatTo16BitPCM(view, 44, samples);
|
|
174
|
+
} else {
|
|
175
|
+
writeFloat32(view, 44, samples);
|
|
176
|
+
}
|
|
177
|
+
return buffer;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
var interleave = function interleave(inputL, inputR) {
|
|
181
|
+
var length = inputL.length + inputR.length;
|
|
182
|
+
var result = new Float32Array(length);
|
|
183
|
+
|
|
184
|
+
var index = 0;
|
|
185
|
+
var inputIndex = 0;
|
|
186
|
+
|
|
187
|
+
while (index < length) {
|
|
188
|
+
result[index++] = inputL[inputIndex];
|
|
189
|
+
result[index++] = inputR[inputIndex];
|
|
190
|
+
inputIndex++;
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
var writeFloat32 = function writeFloat32(output, offset, input) {
|
|
196
|
+
for (var i = 0; i < input.length; i++, offset += 4) {
|
|
197
|
+
output.setFloat32(offset, input[i], true);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
var floatTo16BitPCM = function floatTo16BitPCM(output, offset, input) {
|
|
202
|
+
for (var i = 0; i < input.length; i++, offset += 2) {
|
|
203
|
+
var s = Math.max(-1, Math.min(1, input[i]));
|
|
204
|
+
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
var writeString = function writeString(view, offset, string) {
|
|
209
|
+
for (var i = 0; i < string.length; i++) {
|
|
210
|
+
view.setUint8(offset + i, string.charCodeAt(i));
|
|
211
|
+
}
|
|
123
212
|
};
|