-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
140 lines (120 loc) · 8.41 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import streamlit as st # создания веб-приложений
import sounddevice # запись и воспроизведение звука
import soundfile # для чтения и записи звуковых файлов
import io # модуль io для работы с потоками ввода-вывода
import numpy as np # для работы с массивами и математическими операциями
import librosa # для анализа и обработки аудио
import os # модуль os для работы с файловой системой
import speech_recognition # SpeechRecognition для распознавания речи
import tempfile # временная запись аудио файла
st.title("Система распознания аварийных вызовов")
st.write("Для начала, выберите индекс устройства записи звука из списка доступных устройств на вашем пк в графе 'Настройка средств записи'")
devices = sounddevice.query_devices()
# Вывод списка устройств ввода
input_devices = [device for device in devices if device['max_input_channels'] > 0]
# Вывод стандартного устройства ввода
default_input_device = sounddevice.default.device[0]
default_input_name = devices[default_input_device]['name']
with st.expander("Настройка средств записи"):
st.write(f"Устройство ввода по умолчанию: {default_input_name}. Индекс {default_input_device}.")
st.write(" ")
st.table(input_devices)
# Выбор устройства ввода пользователем
input_device_index = st.selectbox(
"Выберите индекс устройства ввода звука",
options=list(range(len(input_devices))), # Список индексов устройств
index=default_input_device # Значение по умолчанию (стандартное устройство)
)
st.write(f"Выбранное устройство: {input_devices[input_device_index]['name']}")
st.write(" ")
st.write(" ")
st.write(" ")
st.write("**Памятка оператора аварийной службы**")
with st.expander("*Важная информация*"):
st.markdown("- Первый запуск приложения может занимать больше времени.")
st.markdown("- Могут возникать ошибки записи. Приложение об этом предупредит. Проверьте формат входных данных и убедитесь, что устройство ввода аудиосигнала подключено и работает корректно.")
st.markdown("- Точность распознавания аварий составляет 9 из 10 случаев. Тем не менее, алгоритм не учитывает все возможные случаи и носит рекомендательный характер.")
st.markdown("- Иногда возникает аномалия модуля распознания, 'анализ сигнала' может принять разговор оператора с пострадавшим за 'аварийный случай', когда вызов ложный.")
with st.expander("*Ответственность*"):
st.markdown("- Вся ответственность по-прежнему лежит на операторе.")
st.markdown("- Пожалуйста, примите это во внимание, на кону человеческие жизни!")
with st.expander("*Принцип работы*"):
st.markdown("- Временная запись первых 20 секунд.")
st.markdown("- Распознание речи.")
st.markdown("- Анализ спектра частот для выявления признаков аварийной ситуации.")
st.markdown("- Удаление временной записи из 20 секунд.")
st.write(" ")
st.write(" ")
st.write(" ")
st.markdown("Нажмите кнопку 'Начать запись' или загрузите аудио файл, что бы запустить работу.")
st.markdown("В режиме загрузки речевой модуль отсутствует.")
duration = 20 # Запись в течение 20 секунд
sample_rate = 44100 # Частота дискретизации 44100 Гц
channels = 1 # Моно-запись
audio_data = None
# Распозание речи
def recognizeAudio(audio_data):
recognizer = speech_recognition.Recognizer()
with io.BytesIO(audio_data) as buffer:
audio_file = speech_recognition.AudioFile(buffer)
with audio_file as source:
audio = recognizer.record(source, duration=duration, offset=0)
try:
return recognizer.recognize_google(audio, language='ru')
except speech_recognition.UnknownValueError:
return "Речь слишком неразборчивая или ее нет вовсе."
except speech_recognition.RequestError as e:
return "Ошибка при запросе к службе распознавания речи; {0}".format(e)
# Модель. Анализ сигнала
def easy_model(y, sr):
chroma_features = librosa.feature.chroma_stft(y=y, sr=sr)
min_chroma = np.min(chroma_features)
threshold = 0.003046 * 0.02
if min_chroma < threshold: return "Предполагаю, аварийный случай. Вызывайте экстренные службы!"
else: return "Предполагаю, ложный вызов. Решение за вами."
if st.button("Начать запись"):
st.write("Запись пошла...")
audio_data = sounddevice.rec(int(duration * sample_rate), samplerate=sample_rate, channels=channels, device=input_device_index)
sounddevice.wait()
# Сохранение записанного звука в формате WAV (временный файл)
with io.BytesIO() as buffer:
try:
soundfile.write(buffer, audio_data, sample_rate, subtype="PCM_24", format="wav")
# Ожидание завершения записи
sounddevice.wait()
st.write("Запись завершена!")
st.audio(buffer)
st.write(" ")
# Распознавание речи
st.write("Распознавание речи...")
try:
speech_text = recognizeAudio(buffer.getvalue())
st.write("Итог:", speech_text)
if len(speech_text) == 0: st.write("Речь слишком неразборчивая или ее нет вовсе.")
except: st.write("Речь слишком неразборчивая или ее нет вовсе.")
st.write(" ")
# Анализ вызова
st.write("Анализ вызова...")
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_file: # Используем tempfile
temp_file.write(buffer.getvalue()) # Запишем байты в временный файл
y, sr = librosa.load(temp_file.name) # Используем имя файла
st.write(easy_model(y, sr))
temp_file.close() # Закрываем временный файл
except Exception as e: st.error(f"Ошибка при записи: {e}")
st.write(" ")
# Пользователь загружает аудио файл
uploaded_file = st.file_uploader("Загрузите аудио файл", type=["wav", "mp3"])
if uploaded_file is not None:
# Чтение аудио файла
audio_bytes = uploaded_file.read()
# Создание временного файла
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_file:
temp_file.write(audio_bytes)
temp_file_path = temp_file.name
st.write(" ")
st.write("Анализ вызова...")
# Загружаем аудио из временного файла
y, sr = librosa.load(temp_file_path, duration=duration)
# Выполняем анализ
result = easy_model(y, sr)
st.write(result)