我具有以下架构:
my-app/
README.md
node_modules/
package.json
public/
favicon.ico
index.html
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
recorder.js
componentsFolder
Speech.css
Speech.js
我希望导入能够将recorder.js javascript文件导入到Speech.js,但我没有设法做到这一点,只是使用import或require,因为我总是会遇到以下错误:
我收到以下错误:
./src/components/Speech.js
Module not found: You attempted to import /recorder which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.
所以我相信还有另一种可行的方法。
我附加了两个文件:
Speech.js
import React, { Component } from 'react';
// import './Speech.css';
// import './Speech.css';
import axios from 'axios';
import Recorder from '../recorder'
export default class Speech extends Component {
constructor(props) {
super(props);
this.state = {
btn: true,
btnStop: false,
loader: false,
result: false,
resultError: false,
textResult: '',
apiKey: 'd9cf10ae33dfbbd03e58d9adfd0a75ef88159d63', // api key
selected: 'en-US',
items: [
{
text: 'English (United States)',
value: 'en-US'
}
],
data: {
audio: {
content: null
},
config: {
encoding: 'LINEAR16',
sampleRateHertz: 44100,
languageCode: null
}
}
};
}
startUserMedia(stream) {
const input = window.audio_context.createMediaStreamSource(stream);
// Media stream created
// const { Recorder: myRecorder } = require('/recorder');
// console.log(myRecorder);
// require('/recorder');
this.recorder = new Recorder(input);
// Recorder initialised
}
startRecording() {
// Start Recording
this.recorder && this.recorder.record();
this.state.result = false;
this.state.btn = false;
this.state.btnStop = true;
setTimeout(this.stopRecording, 58000);
}
stopRecording() {
// Stopped Recording
this.recorder && this.recorder.stop();
this.state.btnStop = false;
this.state.loader = true;
// create WAV download link using audio data blob
this.processRecording();
this.recorder.clear();
}
processRecording() {
const vm = this;
this.recorder &&
this.recorder.exportWAV(blob => {
const reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const baseData = reader.result;
const base64Data = baseData.replace('data:audio/wav;base64,', '');
vm.data.audio.content = base64Data;
vm.data.config.languageCode = vm.state.selected;
axios
.post(
`https://speech.googleapis.com/v1/speech:recognize?key=${vm.state.apiKey}`,
vm.data
)
.then(response => {
const result = response.data.results[0].alternatives[0];
vm.state.textResult = result.transcript;
vm.state.btn = true;
vm.state.loader = false;
vm.state.result = true;
})
.catch(error => {
vm.state.loader = false;
vm.state.resultError = true;
console.log(`ERROR:${error}`);
});
};
});
}
redirectError() {
window.location.href = 'http://localhost:8080/';
}
componentWillMount() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
window.URL = window.URL || window.webkitURL;
window.audio_context = new AudioContext();
console.log('Audio context set up.');
console.log(
`navigator.getUserMedia ${navigator.getUserMedia ? 'available.' : 'not present!'}`
);
} catch (e) {
alert('No web audio support in this browser!');
}
const that = this;
navigator.getUserMedia(
{
audio: true
},
stream => {
that.state.startUserMedia(stream);
},
e => {
console.log(`No live audio input: ${e}`);
}
);
}
render() {
return (
<layout row wrap>
<select show="btn" items={this.state.items} model="selected" label="Select a language" />
<button onClick={this.startRecording} block round color="primary" dark>
<icon left>mic</icon>
Recording
</button>
<button onClick={this.stopRecording} block round color="error" dark>
<icon left>stop</icon>
Stop
</button>
<div>
<progress-circle indeterminate size="100" width="3" class="orange--text" />
</div>
<transition name="slide">
<div>
<layout row wrap>
<card className="darken-2 orange--text">
<h4 className="text-xs-center">{this.state.textResult}</h4>
</card>
</layout>
</div>
</transition>
<transition name="slide">
<div v-show="resultError" className="text-xs-center">
<layout row wrap>
<col />
<col>
<card className="red darken-3 white--text">
<card-title primary-title>
<div className="headline">An Unexpected Error Occurred</div>
</card-title>
<card-actions>
<button onClick={this.redirectError} flat dark>
Try Again
</button>
</card-actions>
</card>
</col>
<col />
</layout>
</div>
</transition>
</layout>
);
}
}
recorder.js
(function (f) {
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = f()
} else if (typeof define === 'function' && define.amd) {
define([], f)
} else {
var g
if (typeof window !== 'undefined') {
g = window
} else if (typeof global !== 'undefined') {
g = global
} else if (typeof self !== 'undefined') {
g = self
} else {
g = this
}
g.Recorder = f()
}
})(function () {
var define, module, exports
return (function e (t, n, r) {
function s (o, u) {
if (!n[o]) {
if (!t[o]) {
var a = typeof require === 'function' && require
if (!u && a) return a(o, !0)
if (i) return i(o, !0)
var f = new Error("Cannot find module '" + o + "'")
throw f.code = 'MODULE_NOT_FOUND', f
}
var l = n[o] = {
exports: {}
}
t[o][0].call(l.exports, function (e) {
var n = t[o][1][e]
return s(n || e)
}, l, l.exports, e, t, n, r)
}
return n[o].exports
}
var i = typeof require === 'function' && require
for (var o = 0; o < r.length; o++) s(r[o])
return s
})({
1: [function (require, module, exports) {
'use strict'
module.exports = require('./recorder').Recorder
}, {
'./recorder': 2
}],
2: [function (require, module, exports) {
'use strict'
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
}
})()
Object.defineProperty(exports, '__esModule', {
value: true
})
exports.Recorder = undefined
var _inlineWorker = require('inline-worker')
var _inlineWorker2 = _interopRequireDefault(_inlineWorker)
function _interopRequireDefault (obj) {
return obj && obj.__esModule ? obj : {
default: obj
}
}
function _classCallCheck (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function')
}
}
var Recorder = exports.Recorder = (function () {
function Recorder (source, cfg) {
var _this = this
_classCallCheck(this, Recorder)
this.config = {
bufferLen: 4096,
numChannels: 1,
mimeType: 'audio/wav'
}
this.recording = false
this.callbacks = {
getBuffer: [],
exportWAV: []
}
Object.assign(this.config, cfg)
this.context = source.context
this.node = (this.context.createScriptProcessor || this.context.createJavaScriptNode).call(this.context, this.config.bufferLen, this.config.numChannels, this.config.numChannels)
this.node.onaudioprocess = function (e) {
if (!_this.recording) return
var buffer = []
for (var channel = 0; channel < _this.config.numChannels; channel++) {
buffer.push(e.inputBuffer.getChannelData(channel))
}
_this.worker.postMessage({
command: 'record',
buffer: buffer
})
}
source.connect(this.node)
this.node.connect(this.context.destination) // this should not be necessary
var self = {}
this.worker = new _inlineWorker2.default(function () {
var recLength = 0
var recBuffers = []
var sampleRate = undefined
var numChannels = undefined
self.onmessage = function (e) {
switch (e.data.command) {
case 'init':
init(e.data.config)
break
case 'record':
record(e.data.buffer)
break
case 'exportWAV':
exportWAV(e.data.type)
break
case 'getBuffer':
getBuffer()
break
case 'clear':
clear()
break
}
}
function init (config) {
sampleRate = config.sampleRate
numChannels = config.numChannels
initBuffers()
}
function record (inputBuffer) {
for (var channel = 0; channel < numChannels; channel++) {
recBuffers[channel].push(inputBuffer[channel])
}
recLength += inputBuffer[0].length
}
function exportWAV (type) {
var buffers = []
for (var channel = 0; channel < numChannels; channel++) {
buffers.push(mergeBuffers(recBuffers[channel], recLength))
}
var interleaved = undefined
if (numChannels === 2) {
interleaved = interleave(buffers[0], buffers[1])
} else {
interleaved = buffers[0]
}
var dataview = encodeWAV(interleaved)
var audioBlob = new Blob([dataview], {
type: type
})
self.postMessage({
command: 'exportWAV',
data: audioBlob
})
}
function getBuffer () {
var buffers = []
for (var channel = 0; channel < numChannels; channel++) {
buffers.push(mergeBuffers(recBuffers[channel], recLength))
}
self.postMessage({
command: 'getBuffer',
data: buffers
})
}
function clear () {
recLength = 0
recBuffers = []
initBuffers()
}
function initBuffers () {
for (var channel = 0; channel < numChannels; channel++) {
recBuffers[channel] = []
}
}
function mergeBuffers (recBuffers, recLength) {
var result = new Float32Array(recLength)
var offset = 0
for (var i = 0; i < recBuffers.length; i++) {
result.set(recBuffers[i], offset)
offset += recBuffers[i].length
}
return result
}
function interleave (inputL, inputR) {
var length = inputL.length + inputR.length
var result = new Float32Array(length)
var index = 0
var inputIndex = 0
while (index < length) {
result[index++] = inputL[inputIndex]
result[index++] = inputR[inputIndex]
inputIndex++
}
return result
}
function floatTo16BitPCM (output, offset, input) {
for (var i = 0; i < input.length; i++, offset += 2) {
var s = Math.max(-1, Math.min(1, input[i]))
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true)
}
}
function writeString (view, offset, string) {
for (var i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i))
}
}
function encodeWAV (samples) {
var buffer = new ArrayBuffer(44 + samples.length * 2)
var view = new DataView(buffer)
/* RIFF identifier */
writeString(view, 0, 'RIFF')
/* RIFF chunk length */
view.setUint32(4, 36 + samples.length * 2, true)
/* RIFF type */
writeString(view, 8, 'WAVE')
/* format chunk identifier */
writeString(view, 12, 'fmt ')
/* format chunk length */
view.setUint32(16, 16, true)
/* sample format (raw) */
view.setUint16(20, 1, true)
/* channel count */
view.setUint16(22, numChannels, true)
/* sample rate */
view.setUint32(24, sampleRate, true)
/* byte rate (sample rate * block align) */
view.setUint32(28, sampleRate * 4, true)
/* block align (channel count * bytes per sample) */
view.setUint16(32, numChannels * 2, true)
/* bits per sample */
view.setUint16(34, 16, true)
/* data chunk identifier */
writeString(view, 36, 'data')
/* data chunk length */
view.setUint32(40, samples.length * 2, true)
floatTo16BitPCM(view, 44, samples)
return view
}
}, self)
this.worker.postMessage({
command: 'init',
config: {
sampleRate: this.context.sampleRate,
numChannels: this.config.numChannels
}
})
this.worker.onmessage = function (e) {
var cb = _this.callbacks[e.data.command].pop()
if (typeof cb === 'function') {
cb(e.data.data)
}
}
}
_createClass(Recorder, [{
key: 'record',
value: function record () {
this.recording = true
}
}, {
key: 'stop',
value: function stop () {
this.recording = false
}
}, {
key: 'clear',
value: function clear () {
this.worker.postMessage({
command: 'clear'
})
}
}, {
key: 'getBuffer',
value: function getBuffer (cb) {
cb = cb || this.config.callback
if (!cb) throw new Error('Callback not set')
this.callbacks.getBuffer.push(cb)
this.worker.postMessage({
command: 'getBuffer'
})
}
}, {
key: 'exportWAV',
value: function exportWAV (cb, mimeType) {
mimeType = mimeType || this.config.mimeType
cb = cb || this.config.callback
if (!cb) throw new Error('Callback not set')
this.callbacks.exportWAV.push(cb)
this.worker.postMessage({
command: 'exportWAV',
type: mimeType
})
}
}], [{
key: 'forceDownload',
value: function forceDownload (blob, filename) {
var url = (window.URL || window.webkitURL).createObjectURL(blob)
var link = window.document.createElement('a')
link.href = url
link.download = filename || 'output.wav'
var click = document.createEvent('Event')
click.initEvent('click', true, true)
link.dispatchEvent(click)
}
}])
return Recorder
})()
exports.default = Recorder
}, {
'inline-worker': 3
}],
3: [function (require, module, exports) {
'use strict'
module.exports = require('./inline-worker')
}, {
'./inline-worker': 4
}],
4: [function (require, module, exports) {
(function (global) {
'use strict'
var _createClass = (function () {
function defineProperties (target, props) {
for (var key in props) {
var prop = props[key]
prop.configurable = true
if (prop.value) prop.writable = true
}
Object.defineProperties(target, props)
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps)
if (staticProps) defineProperties(Constructor, staticProps)
return Constructor
}
})()
var _classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function')
}
}
var WORKER_ENABLED = !!(global === global.window && global.URL && global.Blob && global.Worker)
var InlineWorker = (function () {
function InlineWorker (func, self) {
var _this = this
_classCallCheck(this, InlineWorker)
if (WORKER_ENABLED) {
var functionBody = func.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1]
var url = global.URL.createObjectURL(new global.Blob([functionBody], {
type: 'text/javascript'
}))
return new global.Worker(url)
}
this.self = self
this.self.postMessage = function (data) {
setTimeout(function () {
_this.onmessage({
data: data
})
}, 0)
}
setTimeout(function () {
func.call(self)
}, 0)
}
_createClass(InlineWorker, {
postMessage: {
value: function postMessage (data) {
var _this = this
setTimeout(function () {
_this.self.onmessage({
data: data
})
}, 0)
}
}
})
return InlineWorker
})()
module.exports = InlineWorker
}).call(this, typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : {})
}, {}]
}, {}, [1])(1)
})
答案 0 :(得分:0)
您指向的文件不存在。您需要从my-app/src/componentsFolder/Speech.js
导入../recorder
答案 1 :(得分:0)
当我们看到错误而不是引起错误的代码时,这很困难。我看到了一些问题,希望其中至少有一个问题。
首先,在您提供的树中,App.css位于树的中间,但不包括缩进。我认为这是不正确的,应该位于/ src文件夹中。我不知道结构中是否还有其他错误。
此外,您的错误表明它正在寻找/ recorder。这也会显得不正确。您要查找“ / recorder”还是“ ./recorder”?后者将是首选进口。另外,您是否要使用recorder.js的export,export default或modules.export?