Alexanrd commited on
Commit
cf9d67c
·
verified ·
1 Parent(s): 0f54f3e

add timestamps for words

Browse files
Files changed (1) hide show
  1. example.py +112 -73
example.py CHANGED
@@ -1,73 +1,112 @@
1
- import sherpa_onnx
2
- import numpy as np
3
- import ujson
4
- from pydub import AudioSegment
5
- from datetime import datetime as dt
6
-
7
-
8
- recognizer = sherpa_onnx.OfflineRecognizer.from_nemo_ctc(
9
- model = "GigaAMv2_ctc_public.onnx",
10
- tokens = "tokens.txt",
11
- feature_dim=64,
12
- num_threads=8,
13
- sample_rate=8000,
14
- decoding_method="greedy_search",
15
- provider="CUDA",
16
- debug = False,
17
- )
18
-
19
- def get_np_array_samples_float32(audio_bytes: bytes, sample_width: int = 2) -> np.ndarray:
20
- """
21
- Преобразует аудио в байтах в массив float32.
22
- :param audio_bytes: Аудиоданные в байтах.
23
- :param sample_width: Размер одного сэмпла в байтах (обычно 2 для 16-битного аудио).
24
- :return: Массив numpy с данными в формате float32.
25
- """
26
-
27
- # Определяем тип данных на основе sample_width
28
- dtype = np.int16 if sample_width == 2 else np.int32
29
-
30
- # Преобразуем байты в массив numpy
31
- samples = np.frombuffer(audio_bytes, dtype=dtype)
32
- samples_float32 = samples.astype(np.float32)
33
- samples_float32 = samples_float32 / 32768
34
-
35
- return samples_float32
36
-
37
-
38
- def simple_recognise(audio_data, ) -> dict:
39
- """
40
- Собираем токены в слова дополнительных вычислений не производит.
41
- :param audio_data: Аудиоданные в формате Audiosegment (puDub).
42
- """
43
-
44
- stream = None
45
- stream = recognizer.create_stream()
46
- audio_data = audio_data.set_frame_rate(8000)
47
- audio_data = audio_data[15000:] # cut here to 15-18 secs
48
- audio_data = audio_data.split_to_mono()[0] # only mono allowed
49
-
50
- # перевод в семплы для распознавания.
51
- samples = get_np_array_samples_float32(audio_data.raw_data, audio_data.sample_width)
52
-
53
- print(f'Audio length - {audio_data.duration_seconds} secs.')
54
-
55
- # передали аудиофрагмент на распознавание
56
- stream.accept_waveform(sample_rate=audio_data.frame_rate, waveform=samples)
57
- recognizer.decode_stream(stream)
58
-
59
- result = ujson.loads(str(stream.result))
60
-
61
- return result
62
-
63
-
64
- if __name__ == '__main__':
65
- file_path = "test.wav"
66
- sound = AudioSegment.from_file(str(file_path))
67
-
68
- time_start = dt.now()
69
- asr_res = simple_recognise(audio_data=sound)
70
- print(
71
- f'Work time = {(dt.now()-time_start).total_seconds()}\n'
72
- )
73
- print(asr_res)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sherpa_onnx
2
+ import numpy as np
3
+ import ujson
4
+ from pydub import AudioSegment
5
+ from datetime import datetime as dt
6
+
7
+
8
+ recognizer = sherpa_onnx.OfflineRecognizer.from_nemo_ctc(
9
+ model = "GigaAMv2_ctc_public.onnx",
10
+ tokens = "tokens.txt",
11
+ feature_dim=64,
12
+ num_threads=8,
13
+ sample_rate=8000,
14
+ decoding_method="greedy_search",
15
+ provider="CUDA",
16
+ debug = False,
17
+ )
18
+
19
+ def get_np_array_samples_float32(audio_bytes: bytes, sample_width: int = 2) -> np.ndarray:
20
+ """
21
+ Преобразует аудио в байтах в массив float32.
22
+ :param audio_bytes: Аудиоданные в байтах.
23
+ :param sample_width: Размер одного сэмпла в байтах (обычно 2 для 16-битного аудио).
24
+ :return: Массив numpy с данными в формате float32.
25
+ """
26
+
27
+ # Определяем тип данных на основе sample_width
28
+ dtype = np.int16 if sample_width == 2 else np.int32
29
+
30
+ # Преобразуем байты в массив numpy
31
+ samples = np.frombuffer(audio_bytes, dtype=dtype)
32
+ samples_float32 = samples.astype(np.float32)
33
+ samples_float32 = samples_float32 / 32768
34
+
35
+ return samples_float32
36
+
37
+
38
+ def simple_recognise(audio_data, ) -> dict:
39
+ """
40
+ :param audio_data: Аудиоданные в формате Audiosegment (puDub).
41
+ """
42
+
43
+ stream = None
44
+ stream = recognizer.create_stream()
45
+ audio_data = audio_data.set_frame_rate(8000)
46
+ audio_data = audio_data[:] # cut here to 15-18 secs
47
+ audio_data = audio_data.split_to_mono()[0] # only mono allowed
48
+
49
+ # перевод в семплы для распознавания.
50
+ samples = get_np_array_samples_float32(audio_data.raw_data, audio_data.sample_width)
51
+
52
+ print(f'Audio length - {audio_data.duration_seconds} secs.')
53
+
54
+ # передали аудиофрагмент на распознавание
55
+ stream.accept_waveform(sample_rate=audio_data.frame_rate, waveform=samples)
56
+ recognizer.decode_stream(stream)
57
+
58
+ result = ujson.loads(str(stream.result))
59
+
60
+ return result
61
+
62
+ def process_gigaam_asr(input_json, time_shift = 0.0):
63
+ """
64
+ Собираем токены в слова дополнительных вычислений не производим.
65
+ :param input_json: json - результат работы stream.result
66
+ :param input_json: time_shift - так как на вход логично будут приходить чанки,
67
+ то для каждого чанка передаём его начало от начала записи.
68
+ """
69
+ # Парсим JSON
70
+ data = input_json
71
+
72
+ # Формируем шаблон результата
73
+ result = {"data": {"result": [], "text": ""}}
74
+
75
+ # Собираем слова из токенов
76
+ words = []
77
+ current_word = ""
78
+ start_time, end_time = 0.0, 0.0
79
+
80
+ for i, token in enumerate(data['tokens']):
81
+ if token != ' ':
82
+ if current_word == "":
83
+ start_time = round((data['timestamps'][i]+time_shift), 3)
84
+ current_word += token
85
+ end_time = round((data['timestamps'][i]+time_shift), 3)
86
+ else:
87
+ if current_word != "":
88
+ words.append({'word': current_word, 'start': start_time, 'end': end_time})
89
+ current_word = ""
90
+
91
+ # Добавляем последнее слово, если оно есть
92
+ if current_word != "":
93
+ words.append({'word': current_word, 'start': start_time, 'end': end_time})
94
+
95
+ # Формируем итоговый массив
96
+ result['data'] = {
97
+ 'result': [{'start': word['start'], 'end': word['end'], 'word': word['word']} for word in words],
98
+ 'text': data['text']
99
+ }
100
+ return result
101
+
102
+ if __name__ == '__main__':
103
+ file_path = "example.wav"
104
+ sound = AudioSegment.from_file(str(file_path))
105
+
106
+ time_start = dt.now()
107
+ asr_res = simple_recognise(audio_data=sound)
108
+ res_w_word_timestamp = process_gigaam_asr(asr_res)
109
+ print(
110
+ f'Work time = {(dt.now()-time_start).total_seconds()}\n'
111
+ )
112
+ print(res_w_word_timestamp)