I want to create web app using STT model by python flask. when user record the voice and send it server, trans it to text on web.
there is my javascript part:
<html>
<head>
<title>STT</title>
</head>
<div style="text-align: center;">
<h2>STT</h2>
<p>
<button type="button" id="record">record</button>
<button type="button" id="stopRecord" disabled>stop</button>
<input type="button" id="sendRecord" value="trans to text">
</p>
<p>
<audio id=recordedAudio></audio>
</p>
</div>
</html>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
let recordBlob;
navigator.mediaDevices.getUserMedia({audio:true})
.then(stream => {handlerFunction(stream)})
function handlerFunction(stream) {
rec = new MediaRecorder(stream);
rec.ondataavailable = e => {
audioChunks.push(e.data);
if (rec.state == "inactive") {
recordBlob = new Blob(audioChunks, {type:'audio/wav; codecs=MS_PCM'});
recordedAudio.src = URL.createObjectURL(blob);
recordedAudio.controls=true;
recordedAudio.autoplay=true;
}
}
}
record.onclick = e => {
record.disabled = true;
record.style.backgroundColor = "blue"
stopRecord.disabled=false;
audioChunks = [];
rec.start();
}
stopRecord.onclick = e => {
record.disabled = false;
stop.disabled=true;
record.style.backgroundColor = "red"
rec.stop();
}
sendRecord.onclick = e => {
let formData = new FormData();
formData.append('data', recordBlob);
console.log('blob', recordBlob);
$.ajax({
type: 'POST',
url: '/result',
data: formData,
contentType: false,
processData: false,
success: function(result) {
console.log('success', result);
$("#chatbox").append(`<p class ="userText"><audio style="background-color:white;" controls> <source src="${Url}" type="audio/wav"></audio></p>`);
$("#chatbox").append(`<p class ="botText"><span>${result.emotion}</span></p>`);
$("#textInput").val("")
},
error: function(result) {
alert('sorry an error occured');
}
});
}
</script>
and there is flask part:
from flask import Flask, render_template, request
import requests, json
import soundfile
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
UPLOAD_FOLDER = "./"
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
@app.route('/')
def index():
return render_template('index.html')
@app.route('/result', methods=['POST'])
def result():
url = "https://kakaoi-newtone-openapi.kakao.com/v1/recognize"
key = 'REST API KEY'
headers = {
"Content-Type": "application/octet-stream",
"Transfer-Encoding":"chunked",
"Authorization": "KakaoAK " key,
}
blobData = request.files['data']
filename = secure_filename(blobData.filename)
filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
blobData.save(filepath)
app.logger.info('blob data : ', blobData)
data, samplerate = soundfile.read(blobData)
soundfile.write('new.wav', data, samplerate, subtype='PCM_16')
with open("new.wav", 'rb') as fp:
audio = fp.read()
res = requests.post(url, headers=headers, data=audio)
return res.text
if __name__=='__main__':
app.debug=True
app.run('0.0.0.0', port=5001)
it comes out error
[2022-02-25 19:27:51,895] ERROR in app: Exception on /result [POST]
Traceback (most recent call last):
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\flask\app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\flask\app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\flask\app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\flask\app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\LJH\Documents\코드스테이츠\개인프로젝트\webapp\flaskapp2\app.py", line 31, in result
data, samplerate = soundfile.read(blobData)
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\soundfile.py", line 372, in read
with SoundFile(file, 'r', samplerate, channels,
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\soundfile.py", line 740, in __init__
self._file = self._open(file, mode_int, closefd)
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\soundfile.py", line 1264, in _open
_error_check(_snd.sf_error(file_ptr),
File "C:\users\ljh\appdata\local\programs\python\python39\lib\site-packages\soundfile.py", line 1455, in _error_check
raise RuntimeError(prefix _ffi.string(err_str).decode('utf-8', 'replace'))
RuntimeError: Error opening <FileStorage: 'blob' ('audio/wav; codecs=ms_pcm')>: File contains data in an unknown format.
127.0.0.1 - - [25/Feb/2022 19:27:51] "POST /result HTTP/1.1" 500 -
I don't know why blob didn't convert to wav...how can I fix it? probably there are many no necessary parts on my javascript code.. I don't know about javascript. I'm sorry for that.
CodePudding user response:
You write the data in a file, the position within the file moves to the end of it. If you then re-read the file using soundfile, you must first jump back to the beginning of the file.
import io
@app.route('/result', methods=['POST'])
def result():
if 'data' in request.files:
file = request.files['data']
# Write the data to a file.
filename = secure_filename(file.filename)
filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
file.save(filepath)
# Jump back to the beginning of the file.
file.seek(0)
# Read the audio data again.
data, samplerate = soundfile.read(file)
with io.BytesIO() as fio:
soundfile.write(
fio,
data,
samplerate=samplerate,
subtype='PCM_16',
format='wav'
)
data = fio.getvalue()
# ...
return '', 400