Spaces:
Running
Running
Yurii Paniv
commited on
Commit
·
13aac28
1
Parent(s):
2a3b35f
Add template with basic frontend recording functionality
Browse files- README.md +6 -1
- main.py +12 -0
- requirements.txt +2 -0
- templates/hello.html +64 -0
README.md
CHANGED
|
@@ -1 +1,6 @@
|
|
| 1 |
-
# voice-recognition-ua
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# voice-recognition-ua
|
| 2 |
+
|
| 3 |
+
```
|
| 4 |
+
export FLASK_APP=main.py
|
| 5 |
+
flask run
|
| 6 |
+
```
|
main.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Flask, render_template
|
| 2 |
+
app = Flask(__name__)
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
@app.route('/')
|
| 6 |
+
def index():
|
| 7 |
+
return render_template('hello.html')
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
@app.route('/recognize', methods=["POST"])
|
| 11 |
+
def recognize():
|
| 12 |
+
return 'Hello, World!'
|
requirements.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Flask==1.1.2
|
| 2 |
+
deepspeech-tflite==0.7.3
|
templates/hello.html
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
|
| 4 |
+
<head>
|
| 5 |
+
<meta charset="UTF-8">
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>Розпізнавання української мови</title>
|
| 8 |
+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
| 9 |
+
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
| 10 |
+
</head>
|
| 11 |
+
|
| 12 |
+
<body>
|
| 13 |
+
<h1>Audio Recording Test</h1>
|
| 14 |
+
<p>Talk for 3 seconds, then you will hear your recording played back</p>
|
| 15 |
+
<button class="btn btn-primary" id="action" onclick="handleAction()">Start recording...</button>
|
| 16 |
+
<script>
|
| 17 |
+
const recordAudio = () =>
|
| 18 |
+
new Promise(async resolve => {
|
| 19 |
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
| 20 |
+
const mediaRecorder = new MediaRecorder(stream, { audioBitsPerSecond: 16000 });
|
| 21 |
+
const audioChunks = [];
|
| 22 |
+
|
| 23 |
+
mediaRecorder.addEventListener("dataavailable", event => {
|
| 24 |
+
audioChunks.push(event.data);
|
| 25 |
+
});
|
| 26 |
+
|
| 27 |
+
const start = () => mediaRecorder.start();
|
| 28 |
+
|
| 29 |
+
const stop = () =>
|
| 30 |
+
new Promise(resolve => {
|
| 31 |
+
mediaRecorder.addEventListener("stop", () => {
|
| 32 |
+
const audioBlob = new Blob(audioChunks);
|
| 33 |
+
|
| 34 |
+
const audioUrl = URL.createObjectURL(audioBlob);
|
| 35 |
+
fetch(`./recognize`, { method: "POST", body: audioBlob })
|
| 36 |
+
.then(response => console.log(response.text()))
|
| 37 |
+
const audio = new Audio(audioUrl);
|
| 38 |
+
const play = () => audio.play();
|
| 39 |
+
resolve({ audioBlob, audioUrl, play });
|
| 40 |
+
});
|
| 41 |
+
|
| 42 |
+
mediaRecorder.stop();
|
| 43 |
+
});
|
| 44 |
+
|
| 45 |
+
resolve({ start, stop });
|
| 46 |
+
});
|
| 47 |
+
|
| 48 |
+
const sleep = time => new Promise(resolve => setTimeout(resolve, time));
|
| 49 |
+
|
| 50 |
+
const handleAction = async () => {
|
| 51 |
+
const recorder = await recordAudio();
|
| 52 |
+
const actionButton = document.getElementById('action');
|
| 53 |
+
actionButton.disabled = true;
|
| 54 |
+
recorder.start();
|
| 55 |
+
await sleep(3000);
|
| 56 |
+
const audio = await recorder.stop();
|
| 57 |
+
audio.play();
|
| 58 |
+
await sleep(3000);
|
| 59 |
+
actionButton.disabled = false;
|
| 60 |
+
}
|
| 61 |
+
</script>
|
| 62 |
+
</body>
|
| 63 |
+
|
| 64 |
+
</html>
|